byte[] buf = new byte[32];
random.nextBytes(buf);
String keyName = HexUtil.bytesToHex(buf);
FreenetURI testKey;
ClientKey insertKey;
ClientKey fetchKey;
ClientKeyBlock block;
if(isSSK) {
testKey = new FreenetURI("KSK", keyName);
insertKey = InsertableClientSSK.create(testKey);
fetchKey = ClientKSK.create(testKey);
block = ((InsertableClientSSK)insertKey).encode(new ArrayBucket(buf), false, false, (short)-1, buf.length, random, COMPRESSOR_TYPE.DEFAULT_COMPRESSORDESCRIPTOR, false);
} else {
block = ClientCHKBlock.encode(buf, false, false, (short)-1, buf.length, COMPRESSOR_TYPE.DEFAULT_COMPRESSORDESCRIPTOR, false);
insertKey = fetchKey = block.getClientKey();
testKey = insertKey.getURI();
}
final Key nodeKey = fetchKey.getNodeKey(false);
System.err.println();
System.err.println("Created random test key "+testKey+" = "+nodeKey);
System.err.println();
Logger.error(RealNodeULPRTest.class, "Starting ULPR test #"+successfulTests+": "+testKey+" = "+fetchKey+" = "+nodeKey);
waitForAllConnected(nodes);
// Fetch the key from each node.
// Only those nodes which have been asked by another node (not directly here) for the key will want it.
// Further, only those nodes on the actual DNF path will learn from their mistakes: a RejectedLoop doesn't tell you much.
// Lets track which nodes have been visited.
final boolean[] visited = new boolean[nodes.length];
NodeDispatcherCallback cb = new NodeDispatcherCallback() {
@Override
public void snoop(Message m, Node n) {
if(((!isSSK) && m.getSpec() == DMT.FNPCHKDataRequest) ||
(isSSK && m.getSpec() == DMT.FNPSSKDataRequest)) {
Key key = (Key) m.getObject(DMT.FREENET_ROUTING_KEY);
if(key.equals(nodeKey)) {
visited[n.getDarknetPortNumber() - DARKNET_PORT_BASE] = true;
}
}
}
};
for(Node node: nodes) {
node.setDispatcherHook(cb);
}
for(int i=0;i<nodes.length;i++) {
System.out.println("Searching from node "+i);
try {
nodes[i%nodes.length].clientCore.realGetKey(fetchKey, false, false, false, REAL_TIME_FLAG);
System.err.println("TEST FAILED: KEY ALREADY PRESENT!!!"); // impossible!
System.exit(EXIT_KEY_EXISTS);
} catch (LowLevelGetException e) {
switch(e.code) {
case LowLevelGetException.DATA_NOT_FOUND:
case LowLevelGetException.ROUTE_NOT_FOUND:
// Expected
System.err.println("Node "+i%nodes.length+" : key not found (expected behaviour)");
continue;
case LowLevelGetException.RECENTLY_FAILED:
System.err.println("Node "+i%nodes.length+" : recently failed (expected behaviour on later tests)");
continue;
default:
System.err.println("Node "+i%nodes.length+" : UNEXPECTED ERROR: "+e.toString());
System.exit(EXIT_UNKNOWN_ERROR_CHECKING_KEY_NOT_EXIST);
}
}
}
// Now we should have a good web of subscriptions set up.
int visitedCount = 0;
StringBuilder sb = new StringBuilder(3*nodes.length+1);
boolean first = true;
for(int i=0;i<visited.length;i++) {
if(!visited[i]) continue;
visitedCount++;
if(!first) sb.append(' ');
first = false;
sb.append(i);
}
System.err.println("Nodes which were asked for the key by another node: "+visitedCount+" : "+sb.toString());
// Store the key to ONE node.
Logger.normal(RealNodeULPRTest.class, "Inserting to node "+(nodes.length-1));
long tStart = System.currentTimeMillis();
nodes[nodes.length-1].store(block.getBlock(), false, false, true, false); // Write to datastore
Logger.normal(RealNodeULPRTest.class, "Inserted to node "+(nodes.length-1));
int x = -1;
while(true) {
x++;
Thread.sleep(1000);
int count = 0;
for(Node node: nodes) {
if(node.hasKey(fetchKey.getNodeKey(false), true, true))
count++;
}
System.err.println("T="+x+" : "+count+'/'+nodes.length+" have the data on test "+successfulTests+".");
Logger.normal(RealNodeULPRTest.class, "T="+x+" : "+count+'/'+nodes.length+" have the data on test "+successfulTests+".");
if(x > 300) {
System.err.println();
System.err.println("TEST FAILED");
System.exit(EXIT_TEST_FAILED);
}
if(count == nodes.length) {
successfulTests++;
long tEnd = System.currentTimeMillis();
long propagationTime = tEnd-tStart;
System.err.println("SUCCESSFUL TEST # "+successfulTests+" in "+propagationTime+"ms!!!");
totalPropagationTime += propagationTime;
System.err.println("Average propagation time: "+(totalPropagationTime / successfulTests)+"ms");
System.err.println();
break;
}
if(x % nodes.length == 0) {
System.err.print("Nodes that do have the data: ");
for(int i=0;i<nodes.length;i++)
if(nodes[i].hasKey(fetchKey.getNodeKey(false), true, true)) {
System.err.print(i+" ");
}
System.err.println();
}
}