-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathNodeCommunicationTest.java
112 lines (104 loc) · 3.84 KB
/
NodeCommunicationTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package base;
import UTXOSet.ElementProof;
import base.network.Block;
import base.network.InvalidBlock;
import base.network.Node;
import org.junit.BeforeClass;
import org.junit.Test;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Random;
import java.util.stream.IntStream;
import static org.junit.Assert.*;
/**
* Class for testing and simulation communication between nodes in Bitcoin network.
* Class uses {@link Block} and {@link InvalidBlock} classes for testing of
* sending valid and invalid blocks.
*
* @author olegggatttor
* @see Node
* @see Block
* @see InvalidBlock
*/
public class NodeCommunicationTest {
private final static int AMOUNT_OF_NODES = 10;
private final static Node[] nodes = new Node[AMOUNT_OF_NODES];
/**
* Invokes before the first test for nodes initialization.
*/
@BeforeClass
public static void init() {
try {
for (int i = 0; i != nodes.length; ++i) {
nodes[i] = new Node();
}
} catch (NoSuchAlgorithmException ignore) {
fail();
}
}
/**
* Sends given {@link Block} to other nodes and asserts the expected result.
* <p>
* Verifies if {@link Block} is accepted by other nodes and {@link InvalidBlock}
* is rejected.
*
* @param from - the position of sender in nodes array.
* @param block - block for sending.
*/
public void sendBlock(final int from, Block block) {
for (int i = 0; i != AMOUNT_OF_NODES; ++i) {
if (i == from) {
continue;
}
if (block instanceof InvalidBlock) {
assertFalse(nodes[i].add(block));
} else {
assertTrue(nodes[i].add(block));
}
}
}
/**
* Testing of sending valid {@link Block} to other nodes. Simulates simple
* communication between nodes in Bitcoin network.
*/
@Test
public void sendingValidBlocks() {
IntStream
.range(0, AMOUNT_OF_NODES * AMOUNT_OF_NODES)
.forEach(nodePos -> {
final Block block = nodes[nodePos % AMOUNT_OF_NODES].generate();
sendBlock(nodePos % AMOUNT_OF_NODES, block);
});
}
/**
* Testing of sending valid and invalid block between nodes in network.
* {@link InvalidBlock} must be rejected and {@link Block} must be
* accepted after verification.
*/
@Test
public void sendingInvalidBlocks() {
final ArrayList<ElementProof> prevProofs = new ArrayList<>();
IntStream
.range(0, (AMOUNT_OF_NODES))
.forEach(nodePos -> {
final Block validBlock = nodes[nodePos].generate();
final ArrayList<ElementProof> invalidProofs = validBlock.getProofs();
if (!invalidProofs.isEmpty()) {
final Random posGenerator = new Random();
final int proofPos = Math.abs(posGenerator.nextInt()) % invalidProofs.size();
final ElementProof proof = invalidProofs.get(proofPos);
if (!prevProofs.isEmpty()) {
invalidProofs.remove(proofPos);
invalidProofs.add(prevProofs.get(Math.abs(posGenerator.nextInt()) % prevProofs.size()));
final Block invalidBlock = new InvalidBlock(validBlock.getCoinsNew(), invalidProofs);
sendBlock(nodePos, invalidBlock);
} else {
sendBlock(nodePos, validBlock);
}
prevProofs.add(proof);
} else {
sendBlock(nodePos % AMOUNT_OF_NODES, validBlock);
}
});
}
}