Commit 04a8e63c authored by Michel Schudel's avatar Michel Schudel

Verfijning van de opdracht.

parent 4daaf707
......@@ -121,7 +121,7 @@ Maak hiervoor een static factory method `create` op de `Blockchain` class met al
Nu we de code voor een initiele blockchain hebben, dienen we deze daadwerklijk te creeren.
Maak in de Spring component `BlockChainManager` een nieuw field `blockChain` van type `BlockChain`. Initialiseer in de `init` method (die middels een `@PostConstruct` annotatie afgaat wanneer je de spring container start) nu het field door middel van een aanroep naar de static `create` factory method.
Maak in de Spring component `BlockChainManager` een nieuw field `blockchain` van type `BlockChain`. Initialiseer in de `init` method (die middels een `@PostConstruct` annotatie afgaat wanneer je de spring container start) nu het field door middel van een aanroep naar de static `create` factory method.
Laat de functie `retrieveBlockChain` het blockchain field retourneren.
......
package nl.craftsmen.blockchain.craftscoinnode;
import nl.craftsmen.blockchain.craftscoinnode.blockchain.Block;
import nl.craftsmen.blockchain.craftscoinnode.blockchain.BlockChain;
import nl.craftsmen.blockchain.craftscoinnode.blockchain.Blockchain;
import nl.craftsmen.blockchain.craftscoinnode.blockchain.BlockchainService;
import nl.craftsmen.blockchain.craftscoinnode.network.Network;
import nl.craftsmen.blockchain.craftscoinnode.transaction.Transaction;
......@@ -59,7 +59,7 @@ public class CraftsCoinRestController {
* @return the blockchain of this node
*/
@GetMapping("/api/blockchain")
public BlockChain getBlockchain() {
public Blockchain getBlockchain() {
return blockchainService.retrieveBlockChain();
}
......
......@@ -12,19 +12,19 @@ import java.util.Set;
import java.util.stream.Collectors;
@JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, isGetterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)
public class BlockChain {
public class Blockchain {
private List<Block> chain = new ArrayList<>();
public static BlockChain create() {
BlockChain blockChain = new BlockChain();
blockChain.createNewBlock(100, "1", Collections.emptySet());
return blockChain;
public static Blockchain create() {
Blockchain blockchain = new Blockchain();
blockchain.createNewBlock(100, "1", Collections.emptySet());
return blockchain;
}
//default constructor, needed for json deserialization
@SuppressWarnings({"unused", "WeakerAccess"})
public BlockChain() {
public Blockchain() {
}
......
......@@ -24,16 +24,16 @@ final class BlockchainRepository {
this.instanceInfo = instanceInfo;
}
BlockChain loadBlockChain() {
Blockchain loadBlockChain() {
try {
File file = createBlockchainFileForThisNode();
LOGGER.info("trying to load blockchain for this node under filename {}", file.getName());
if (file.exists()) {
LOGGER.info("existing local blockchain found, loading...");
ObjectMapper objectMapper = new ObjectMapper();
BlockChain blockChain = objectMapper.readValue(file, BlockChain.class);
Blockchain blockchain = objectMapper.readValue(file, Blockchain.class);
LOGGER.info("blockchain succesfully loaded!");
return blockChain;
return blockchain;
} else {
return null;
}
......@@ -42,13 +42,13 @@ final class BlockchainRepository {
}
}
void saveBlockChain(BlockChain blockChain) {
void saveBlockChain(Blockchain blockchain) {
try {
File file = createBlockchainFileForThisNode();
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
LOGGER.info("saving blockchain");
objectMapper.writeValue(file, blockChain);
objectMapper.writeValue(file, blockchain);
LOGGER.info("blockchain succesfully saved!");
} catch (IOException e) {
throw new RuntimeException(e);
......
......@@ -22,7 +22,7 @@ public class BlockchainService {
private static final BigDecimal CRAFTSCOIN_MINING_REWARD = BigDecimal.TEN;
private BlockChain blockChain;
private Blockchain blockchain;
private Network network;
private BlockchainRepository blockchainRepository;
private TransactionPool transactionPool;
......@@ -46,17 +46,17 @@ public class BlockchainService {
}
private void initializeBlockchain() {
if (this.blockChain == null) {
this.blockChain = blockchainRepository.loadBlockChain();
if (this.blockChain == null) {
this.blockChain = BlockChain.create();
blockchainRepository.saveBlockChain(this.blockChain);
if (this.blockchain == null) {
this.blockchain = blockchainRepository.loadBlockChain();
if (this.blockchain == null) {
this.blockchain = Blockchain.create();
blockchainRepository.saveBlockChain(this.blockchain);
}
}
}
public BlockChain retrieveBlockChain() {
return this.blockChain;
public Blockchain retrieveBlockChain() {
return this.blockchain;
}
public long newTransaction(Transaction transaction, String sourcePeer) {
......@@ -69,36 +69,36 @@ public class BlockchainService {
transactionPool.addTransaction(transaction);
network.notifyPeersOfNewTransaction(transaction, sourcePeer);
}
return this.blockChain.getIndexOfNextBlock();
return this.blockchain.getIndexOfNextBlock();
}
public Block mine() {
if (this.transactionPool.getCurrentTransactions().isEmpty()) {
throw new RuntimeException("no pending transactions, nothing to mine.");
}
long newProof = blockChain.proofOfWork();
long newProof = blockchain.proofOfWork();
//reward the miner
Transaction transaction = new Transaction("0", miningWalletId, CRAFTSCOIN_MINING_REWARD);
transactionPool.addTransaction(transaction);
String previousHash = HashUtil.hash(this.blockChain.getLastBlock());
Block newBlock = this.blockChain.createNewBlock(newProof, previousHash, transactionPool.getCurrentTransactions());
blockchainRepository.saveBlockChain(this.blockChain);
String previousHash = HashUtil.hash(this.blockchain.getLastBlock());
Block newBlock = this.blockchain.createNewBlock(newProof, previousHash, transactionPool.getCurrentTransactions());
blockchainRepository.saveBlockChain(this.blockchain);
transactionPool.clearTransactions();
network.notifyPeersOfNewBlock(newBlock, null);
return newBlock;
}
private void reachConsensus() {
List<BlockChain> otherChains = network.retrieveBlockchainsFromPeers();
List<Blockchain> otherChains = network.retrieveBlockchainsFromPeers();
LOGGER.info("blockchains from peers received. Checking...");
for (BlockChain otherChain : otherChains) {
for (Blockchain otherChain : otherChains) {
if (this.blockChain == null || (otherChain.getBlockHeight() > this.blockChain.getBlockHeight() && otherChain.isValid())) {
if (this.blockchain == null || (otherChain.getBlockHeight() > this.blockchain.getBlockHeight() && otherChain.isValid())) {
LOGGER.info("received a blockchain that is better than my currect chain. Replacing current chain.");
this.blockChain = otherChain;
this.blockchain = otherChain;
clearConfirmedTransactions();
blockchainRepository.saveBlockChain(blockChain);
blockchainRepository.saveBlockChain(blockchain);
break;
}
}
......@@ -106,11 +106,11 @@ public class BlockchainService {
public void newBlockReceived(Block block, String sourcePeer) {
LOGGER.info("received new block: {}", block);
if (blockChain.isNewBlockValid(block)) {
if (blockchain.isNewBlockValid(block)) {
LOGGER.info("block is valid, adding it to the blockchain.");
this.blockChain.addBlock(block);
this.blockchain.addBlock(block);
this.network.notifyPeersOfNewBlock(block, sourcePeer);
blockchainRepository.saveBlockChain(blockChain);
blockchainRepository.saveBlockChain(blockchain);
clearConfirmedTransactions();
} else {
......@@ -120,11 +120,11 @@ public class BlockchainService {
private void clearConfirmedTransactions() {
LOGGER.info("removing all confirmed transactions from the transaction pool");
transactionPool.clearTransactions(blockChain.getAllTransactions());
transactionPool.clearTransactions(blockchain.getAllTransactions());
}
public boolean isValid() {
return this.blockChain.isValid();
return this.blockchain.isValid();
}
public Set<Transaction> getPendingTransactions() {
......
package nl.craftsmen.blockchain.craftscoinnode.network;
import nl.craftsmen.blockchain.craftscoinnode.blockchain.Block;
import nl.craftsmen.blockchain.craftscoinnode.blockchain.BlockChain;
import nl.craftsmen.blockchain.craftscoinnode.blockchain.Blockchain;
import nl.craftsmen.blockchain.craftscoinnode.transaction.Transaction;
import nl.craftsmen.blockchain.craftscoinnode.util.InstanceInfo;
import org.slf4j.Logger;
......@@ -138,11 +138,11 @@ public class Network {
return peersForRemote;
}
public List<BlockChain> retrieveBlockchainsFromPeers() {
List<BlockChain> blockchainList = new ArrayList<>();
public List<Blockchain> retrieveBlockchainsFromPeers() {
List<Blockchain> blockchainList = new ArrayList<>();
LOGGER.info("asking the following peers for their blockhain: {}", peers);
for (String node : peers) {
BlockChain otherChain = restTemplate.getForObject("http://" + node + "/api/blockchain", BlockChain.class);
Blockchain otherChain = restTemplate.getForObject("http://" + node + "/api/blockchain", Blockchain.class);
LOGGER.info("received blockchain from peer {}, adding it to the list.", node);
blockchainList.add(otherChain);
}
......
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