Commit 89eff66f authored by Schudel, MJ (Michel)'s avatar Schudel, MJ (Michel)

added unit tests for block and transactions.

parent 1e4bbf0e
......@@ -11,4 +11,5 @@ class CraftsCoinConfig {
protected RestTemplate restTemplate() {
return new RestTemplate();
}
}
......@@ -39,13 +39,13 @@ public class Blockchain {
/**
* Mines a new block. Adds all the transactions,
* calculates the proof and puts a hash of the previous block in the new block.
* calculates the proof and puts a createHashOf of the previous block in the new block.
*
* @param transactionsToBeIncluded the transactions the be included in the block.
* @return the new block.
*/
public Block mineNewBlock(Set<Transaction> transactionsToBeIncluded) {
String previousHash = HashUtil.hash(this.getLastBlock());
String previousHash = HashUtil.createHashOf(this.getLastBlock());
Block block = new Block(getIndexOfLastBlock() + 1, Instant
.now()
.toEpochMilli(), transactionsToBeIncluded, this.proofOfWork(), previousHash);
......@@ -130,13 +130,13 @@ public class Blockchain {
/**
* Checks if this blockchain is valid.
* A blockchain is valid if all the proofs are correct and all previous hashes point to the hash of the last block.
* A blockchain is valid if all the proofs are correct and all previous hashes point to the createHashOf of the last block.
*
* @return if this blockchain is valid.
*/
public boolean isValid() {
for (int i = chain.size() - 1; i >= 1; i--) {
if (!chain.get(i).getPreviousHash().equals(HashUtil.hash(chain.get(i - 1)))) {
if (!chain.get(i).getPreviousHash().equals(HashUtil.createHashOf(chain.get(i - 1)))) {
return false;
}
if (!validProof(chain.get(i - 1).getProof(), chain.get(i).getProof())) {
......@@ -148,20 +148,20 @@ public class Blockchain {
/**
* Checks if a new block is valid with respect to this blockchain.
* A new block is valid if the proof of the new block is correct and the previoushash matches the hash of the block before.
* A new block is valid if the proof of the new block is correct and the previoushash matches the createHashOf of the block before.
*
* @param newBlock the new block.
* @return true if the new block is valid, false otherwise.
*/
public boolean isNewBlockValid(Block newBlock) {
Block lastBlock = getLastBlock();
return lastBlock == null || newBlock.getPreviousHash().equals(HashUtil.hash(lastBlock)) && validProof(lastBlock.getProof(), newBlock.getProof());
return lastBlock == null || newBlock.getPreviousHash().equals(HashUtil.createHashOf(lastBlock)) && validProof(lastBlock.getProof(), newBlock.getProof());
}
/**
* Find the proof of work for the next block.
* Simple Proof of Work Algorithm:
* - Find a number p' such that hash(p + p') contains leading 4 zeroes, where p is the previous p'
* - Find a number p' such that createHashOf(p + p') contains leading 4 zeroes, where p is the previous p'
* - p is the previous proof, and p' is the new proof
*/
private long proofOfWork() {
......@@ -175,7 +175,7 @@ public class Blockchain {
}
private boolean validProof(long previousProof, long currentProof) {
String hash = HashUtil.createHash(previousProof + "" + currentProof);
String hash = HashUtil.createHashOf(previousProof + "" + currentProof);
return hash.startsWith("0000");
}
......@@ -190,4 +190,5 @@ public class Blockchain {
private boolean otherChainIsHigher(Blockchain otherChain) {
return otherChain.getBlockHeight() > this.getBlockHeight();
}
}
......@@ -10,15 +10,15 @@ import java.security.NoSuchAlgorithmException;
class HashUtil {
/**
* Produces a SHA-256 hex-encoded hash string of a block.
* Produces a SHA-256 hex-encoded createHashOf string of a block.
* @param block the block.
* @return a has string in Hex format, like 'da348aff2d'
*/
static String hash(Block block) {
static String createHashOf(Block block) {
try {
ObjectMapper mapper = new ObjectMapper();
String blockString = mapper.writeValueAsString(block);
return createHash(blockString);
return createHashOf(blockString);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
......@@ -27,11 +27,11 @@ class HashUtil {
/**
* Produces a SHA-256 hex-encoded hash string of a string.
* Produces a SHA-256 hex-encoded createHashOf string of a string.
* @param aString the string.
* @return a has string in Hex format, like 'da348aff2d'
*/
static String createHash(String aString) {
static String createHashOf(String aString) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(aString.getBytes());
......
......@@ -21,7 +21,7 @@ import java.util.Set;
class PeersRepository {
private InstanceInfo instanceInfo;
private ObjectMapper objectMapper = new ObjectMapper();
private static final Logger LOGGER = LoggerFactory.getLogger(PeersRepository.class);
......@@ -40,7 +40,6 @@ class PeersRepository {
LOGGER.info("trying to load peers for this node under filename {}", file.getName());
if (file.exists()) {
LOGGER.info("existing peers file found, loading...");
ObjectMapper objectMapper = new ObjectMapper();
TypeReference<Set<String>> typeRef
= new TypeReference<Set<String>>() {
};
......@@ -48,6 +47,7 @@ class PeersRepository {
LOGGER.info("peers succesfully loaded!");
return peers;
} else {
LOGGER.info("no peers file found, returning empty peers list.");
return new HashSet<>();
}
} catch (IOException e) {
......
#indicates the port this node is running on.
server.port=8080
#if no peers are known to this node, it will try to connect to the node below in an attempt
#to connect to the peer-to-peer network and retrieve known peers from that node.
#of course, when the current running node happens to be the bootstrap node, nothing will happen.
bootstrap.peer.host=localhost
bootstrap.peer.port=8080
#walletId that is used to deposit the reward of succesfully mining a block.
miningWalletId=me
#set the property below to the correct, reachable dns address if the application doesn't find out this node's ip address correctly.
#node.ipAdress=x.x.x.x
\ No newline at end of file
......@@ -7,7 +7,7 @@ import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class BlockchainServiceApplicationTests {
public class BlockchainServiceApplicationIT {
@Test
......
package nl.craftsmen.blockchain.craftscoinnode.blockchain;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class HashUtilTest {
@Test
public void testHash() {
String hash = HashUtil.createHashOf("I can see my house from here");
assertThat(hash).isEqualTo("c6599690d709c8240563146cf0e04a54cbe3a37b621e5ba8ceb6d5e4d345deae");
}
}
\ No newline at end of file
package nl.craftsmen.blockchain.craftscoinnode.network;
import com.fasterxml.jackson.databind.ObjectMapper;
import nl.craftsmen.blockchain.craftscoinnode.util.InstanceInfo;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashSet;
import java.util.Set;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class PeersRepositoryTest {
private static final String PEERNAME = "192.168.0.2:8080";
private static final String THISNODE = "thistestnode:8080";
private static final String THISNODE_OTHER = "thistestnodeother:8080";
private InstanceInfo instanceInfo = mock(InstanceInfo.class);
private PeersRepository peersRepository;
@Before
public void setup() {
peersRepository = new PeersRepository(instanceInfo);
}
@Test
public void loadingNotExistantFileProducesEmptyPeerList() {
when(instanceInfo.getNode()).thenReturn(THISNODE_OTHER);
assertThat(peersRepository.loadPeers()).isEmpty();
}
@Test
public void testSaveAndLoad() {
when(instanceInfo.getNode()).thenReturn(THISNODE);
Set<String> peers = new HashSet<>();
peers.add(PEERNAME);
peersRepository.savePeers(peers);
Set<String> loadedPeers = peersRepository.loadPeers();
assertThat(loadedPeers).containsExactly(PEERNAME);
}
@After
public void cleanup() throws IOException {
Path path = Paths.get(System.getProperty("user.dir"), "thistestnode8080-peers.json");
Files.deleteIfExists(path);
}
}
\ No newline at end of file
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