Document BlockQueue
This commit is contained in:
parent
8ae2e9a3a4
commit
8b381635e3
|
@ -11,6 +11,10 @@ import java.util.concurrent.ConcurrentLinkedDeque;
|
|||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
/**
|
||||
* The processing queue for blocks to be validated and added to the blockchain.
|
||||
* This class also maintains the list of hashes from the peer with the heaviest sub-tree.
|
||||
* Based on these hashes, blocks are added to the queue.
|
||||
*
|
||||
* @author Roman Mandeleil
|
||||
* Created on: 27/07/2014 11:28
|
||||
*/
|
||||
|
@ -18,9 +22,17 @@ public class BlockQueue {
|
|||
|
||||
private static Logger logger = LoggerFactory.getLogger("blockchain");
|
||||
|
||||
/** The list of hashes of the heaviest chain on the network,
|
||||
* for which this client doesn't have the blocks yet */
|
||||
private Deque<byte[]> blockHashQueue = new ConcurrentLinkedDeque<>();
|
||||
|
||||
/** Queue with blocks to be validated and added to the blockchain */
|
||||
private Queue<Block> blockReceivedQueue = new ConcurrentLinkedQueue<>();
|
||||
|
||||
/** Highest known total difficulty, representing the heaviest chain on the network */
|
||||
private BigInteger highestTotalDifficulty;
|
||||
|
||||
/** Last block in the queue to be processed */
|
||||
private Block lastBlock;
|
||||
|
||||
private Timer timer = new Timer("BlockQueueTimer");
|
||||
|
@ -33,6 +45,9 @@ public class BlockQueue {
|
|||
}, 10, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processing the queue adding blocks to the chain.
|
||||
*/
|
||||
private void nudgeQueue() {
|
||||
if (blockReceivedQueue.isEmpty())
|
||||
return;
|
||||
|
@ -41,18 +56,28 @@ public class BlockQueue {
|
|||
WorldManager.getInstance().getBlockchain().add(block);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a list of blocks to the processing queue.
|
||||
* The list is validated by making sure the first block in the received list of blocks
|
||||
* is the next expected block number of the queue.
|
||||
*
|
||||
* The queue is configured to contain a maximum number of blocks to avoid memory issues
|
||||
* If the list exceeds that, the rest of the received blocks in the list are discarded.
|
||||
*
|
||||
* @param blockList - the blocks received from a peer to be added to the queue
|
||||
*/
|
||||
public void addBlocks(List<Block> blockList) {
|
||||
|
||||
Block lastReceivedBlock = blockList.get(blockList.size() - 1);
|
||||
Block lastReceivedBlock = blockList.get(0);
|
||||
if (lastReceivedBlock.getNumber() != getLastBlock().getNumber() + 1)
|
||||
return;
|
||||
|
||||
for (int i = blockList.size() - 1; i >= 0; --i) {
|
||||
|
||||
for (Block block : blockList) {
|
||||
|
||||
if (blockReceivedQueue.size() > SystemProperties.CONFIG.maxBlocksQueued())
|
||||
return;
|
||||
|
||||
this.lastBlock = blockList.get(i);
|
||||
this.lastBlock = block;
|
||||
logger.trace("Last block now index: [{}]", lastBlock.getNumber());
|
||||
blockReceivedQueue.add(lastBlock);
|
||||
}
|
||||
|
@ -60,25 +85,35 @@ public class BlockQueue {
|
|||
blockReceivedQueue.size());
|
||||
}
|
||||
|
||||
public BigInteger getHighestTotalDifficulty() {
|
||||
return highestTotalDifficulty;
|
||||
}
|
||||
|
||||
public void setHighestTotalDifficulty(BigInteger highestTotalDifficulty) {
|
||||
this.highestTotalDifficulty = highestTotalDifficulty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last block in the queue. If the queue is empty,
|
||||
* this will return the last block added to the blockchain.
|
||||
*
|
||||
* @return The last known block this client on the network
|
||||
*/
|
||||
public Block getLastBlock() {
|
||||
if (blockReceivedQueue.isEmpty())
|
||||
return WorldManager.getInstance().getBlockchain().getLastBlock();
|
||||
return lastBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the queue of hashes of blocks to be retrieved
|
||||
* and add the best hash to the top of the queue
|
||||
*
|
||||
* @param hash - the best hash
|
||||
*/
|
||||
public void setBestHash(byte[] hash) {
|
||||
blockHashQueue.clear();
|
||||
blockHashQueue.addLast(hash);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last added hash to the queue representing
|
||||
* the latest known block on the network
|
||||
*
|
||||
* @return The best hash on the network known to the client
|
||||
*/
|
||||
public byte[] getBestHash() {
|
||||
return blockHashQueue.peekLast();
|
||||
}
|
||||
|
@ -86,7 +121,13 @@ public class BlockQueue {
|
|||
public void addHash(byte[] hash) {
|
||||
blockHashQueue.addLast(hash);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a list of hashes from blocks that still need to be downloaded.
|
||||
*
|
||||
* @param amount - the number of hashes to return
|
||||
* @return A list of hashes for which blocks need to be retrieved.
|
||||
*/
|
||||
public List<byte[]> getHashes(int amount) {
|
||||
List<byte[]> hashes = new ArrayList<>();
|
||||
for (int i = 0; i < amount; i++) {
|
||||
|
@ -113,11 +154,28 @@ public class BlockQueue {
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public BigInteger getHighestTotalDifficulty() {
|
||||
return highestTotalDifficulty;
|
||||
}
|
||||
|
||||
public void setHighestTotalDifficulty(BigInteger highestTotalDifficulty) {
|
||||
this.highestTotalDifficulty = highestTotalDifficulty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current number of blocks in the queue
|
||||
*
|
||||
* @return the current number of blocks in the queue
|
||||
*/
|
||||
public int size() {
|
||||
return blockReceivedQueue.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel and purge the timer-thread that
|
||||
* processes the blocks in the queue
|
||||
*/
|
||||
public void close() {
|
||||
timer.cancel();
|
||||
timer.purge();
|
||||
|
|
Loading…
Reference in New Issue