public static Long getLatestBlockTime(int key_databaseid) { Long latestBlockTime; if (Settings.DONT_REMOVE_UNUSED_MESSAGES) { latestBlockTime = Long.MIN_VALUE; } else { channelIdToLatestBlockTimeLock.lock(); latestBlockTime = channelIdToLatestBlockTime.get(key_databaseid); if (latestBlockTime == null) { System.out.println("search in db: " + key_databaseid); latestBlockTime = Test.messageStore.getLatestBlocktime(key_databaseid); channelIdToLatestBlockTime.put(key_databaseid, latestBlockTime); Log.put("latestblocktime: " + latestBlockTime, 5); } else { Log.put("latestblocktime: " + latestBlockTime + " (restored from memory)", 5); } channelIdToLatestBlockTimeLock.unlock(); } return latestBlockTime; }
@Override public void run() { // // try { // sleep(2000); // } catch (InterruptedException ex) { // } final String orgName = Thread.currentThread().getName(); Thread.currentThread().setName(orgName + " - MessageDownloader"); while (!Main.shutdown) { lastRun = System.currentTimeMillis(); try { // System.out.println("new round"); boolean shortWait = false; if (!isActive()) { try { sleep(5000); } catch (InterruptedException ex) { } continue; } boolean requestedOne = false; boolean soutedPublicMsgsMax = false; triggered = false; // System.out.println("Scanning msgs i want to have..."); ArrayList<Peer> clonedPeerList = Test.getClonedPeerList(); Collections.sort( clonedPeerList, new Comparator<Peer>() { @Override public int compare(Peer t, Peer t1) { if (t == null || t1 == null) { return Integer.MIN_VALUE; } return (t1.getMessageLoadedCount() - t.getMessageLoadedCount()); } }); // System.out.println("loaded: " + // clonedPeerList.get(0).getMessageLoadedCount()); // System.out.println("top: " + clonedPeerList.get(0).getMessageLoadedCount() + " low: " + // clonedPeerList.get(clonedPeerList.size() - 1).getMessageLoadedCount()); for (Peer p : clonedPeerList) { // if (!p.isConnected() || System.currentTimeMillis() - p.connectedSince < 500) { if (!p.isConnected() || !p.isAuthed() || !p.isCryptedConnection()) { continue; } if (p.requestedMsgs > MAX_REQUEST_PER_PEER || p.requestedMsgs > p.maxSimultaneousRequests || System.currentTimeMillis() - p.connectedSince < 1000 * 2) { // if (System.currentTimeMillis() - p.connectedSince < 1000 * 2) { shortWait = true; Log.put( "shortwait... reason: " + (p.requestedMsgs > MAX_REQUEST_PER_PEER) + " " + (p.requestedMsgs > p.maxSimultaneousRequests) + " " + (System.currentTimeMillis() - p.connectedSince < 1000 * 10), 2); continue; } // //Damit der download erstmal nur sehr langsam pro peer laeuft... // if (System.currentTimeMillis() - p.lastActionOnConnection < 350) { // shortWait = true; // continue; // } // System.out.println("asdzadgg " + Settings.MAXPUBLICMSGS + " > " + publicMsgsLoaded); if (Settings.MAXPUBLICMSGS > publicMsgsLoaded) { int maxLoadPub = Settings.MAXPUBLICMSGS - publicMsgsLoaded; synchronized (p.getPendingMessages()) { int i = 0; HashMap<Integer, RawMsg> asdf = (HashMap<Integer, RawMsg>) p.getPendingMessagesPublic().clone(); // System.out.println("asdbashd " + asdf.size()); for (Entry<Integer, RawMsg> entry : asdf.entrySet()) { i++; if (i >= maxLoadPub) { break; } // System.out.println("MOVED"); p.getPendingMessages().put(entry.getKey(), entry.getValue()); p.getPendingMessagesPublic().remove(entry.getKey()); } } } HashMap<Integer, RawMsg> hm; synchronized (p.getPendingMessages()) { hm = ((HashMap<Integer, RawMsg>) p.getPendingMessages().clone()); } // System.out.println("MSG Downloader: " + p.ip + ":" + p.port + " // PendingMsgs: " + hm.size() + " Requested: " + p.requestedMsgs); int msgsRequestedThisCycle = 0; for (Entry<Integer, RawMsg> entry : hm.entrySet()) { // so not all MAX_REQUEST_PER_PEER are loaded from one peer. if (msgsRequestedThisCycle > 20) { shortWait = true; // System.out.println("shortwait: msgsRequestedThisCycle"); break; } // int bufferWaiting = 0; // synchronized (p.writeBuffer) { // bufferWaiting = p.writeBuffer.position(); // } // // if (bufferWaiting > 5) { // System.out.println("something in buffer, not requesting // new msgs from this peer: " + p.getIp()); // shortWait = true; // break; // } RawMsg m = entry.getValue(); int messageId = entry.getKey(); RawMsgEntry asEntryMsg = new RawMsgEntry(m); // if (m.public_type == 1) { // //stick!! // // System.out.println("Stick: What to do? " + myMessageId); // // } int myMessageId = MessageHolder.contains(m); // check if SQLTransactionRollbackException occured due to much message inserts if (myMessageId == -2) { sleep(500); continue; } if (p.getPeerTrustData() == null) { Log.put("no trust data found, not downloading messages from node...", 80); synchronized (p.getPendingMessages()) { p.getPendingMessages().remove(messageId); } // Log.put("|", 200); continue; } if (p.getPeerTrustData() != null && myMessageId != -1) { RawMsg rawMsg = MessageHolder.getRawMsg(myMessageId); if (rawMsg == null) { System.out.println( "contains message but no content? likely message was removed because of wrong signature."); continue; } if (!rawMsg.verified) { Log.put("message in db but not verified, check again next run", 80); continue; } boolean removed = Test.messageStore.removeMessageToSend( p.getPeerTrustData().internalId, myMessageId); Log.put( "removed msg: " + p.ip + " " + p.getPeerTrustData().internalId + " - " + myMessageId + " -- " + m.public_type + " - " + removed, 80); if (!removed && !p.removedSendMessages.contains(myMessageId)) { Log.put("not removed.... sending to other node", 80); m.database_Id = myMessageId; m.key.database_id = Test.messageStore.getPubkeyId(m.key); p.writeMessage(m); p.removedSendMessages.add(myMessageId); } //// if (!removed) { //// Log.put("not removed.... sending to other // node", 80); //// m.database_Id = myMessageId; //// m.key.database_id = // Test.messageStore.getPubkeyId(m.key); //// p.writeMessage(m); //// } } if (myMessageId != -1) { synchronized (p.getPendingMessages()) { p.getPendingMessages().remove(messageId); } Log.put("|", 200); continue; } // i send him a mesage to remove which i dont have, he answered that i should remove // this message, but i dont have it if (messageId == -1) { synchronized (p.getPendingMessages()) { p.getPendingMessages().remove(messageId); } Log.put( "i send him a mesage to remove which i dont have, he answered that i should remove this message, but i dont have it", 50); continue; } // This is just a hack for low priority msgs, see explanation after definition of // Settings.REDUCE_TRAFFIC!!! if (Settings.REDUCE_TRAFFIC && m.public_type >= 100) { synchronized (p.getPendingMessages()) { p.getPendingMessages().remove(messageId); } Log.put("removed message, reduce traffic!!!", 40); continue; } m.key.database_id = Test.messageStore.getPubkeyId(m.key); // System.out.println("int: " + m.key.database_id); if (m.public_type == 20 && getLatestBlockTime(m.key.database_id) > m.timestamp) { synchronized (p.getPendingMessages()) { p.getPendingMessages().remove(messageId); } p.writeBufferLock.lock(); if (p.writeBuffer == null) { p.writeBufferLock.unlock(); return; } ECKey k = m.key; if (!p.peerTrustData.keyToIdMine.contains(k.database_id)) { p.peerTrustData.keyToIdMine.add(k.database_id); // int indexOf = keyToIdMine.indexOf(k); int indexOf = m.key.database_id; p.writeBuffer.put((byte) 4); p.writeBuffer.put(k.getPubKey()); p.writeBuffer.putInt(indexOf); Log.put("key introduced", 0); } // m.database_Id = messageId; // m.key.database_id = Test.messageStore.getPubkeyId(m.key); if (p.writeBuffer.remaining() < 1 + 4 + 1 + 8 + 4 + 4) { ByteBuffer oldbuffer = p.writeBuffer; p.writeBuffer = ByteBuffer.allocate(p.writeBuffer.capacity() + 50); p.writeBuffer.put(oldbuffer.array()); p.writeBuffer.position(oldbuffer.position()); System.out.println("writebuffer was raised..."); } p.writeBuffer.put((byte) 5); p.writeBuffer.putInt(m.key.database_id); p.writeBuffer.put(m.public_type); p.writeBuffer.putLong(m.timestamp); p.writeBuffer.putInt(m.nonce); p.writeBuffer.putInt( -1); // TODO: change int to long with offset in case database has much more // entries!! // -1 because i dont have this message and i dont want it too! Log.put( "kDBid: " + m.key.database_id + " public_type: " + m.public_type + " time: " + m.timestamp + " nonce: " + m.nonce + " mdbid: " + m.database_Id, 0); p.writeBufferLock.unlock(); p.setWriteBufferFilled(); Log.put("removed message, already in block!!!", -30); continue; } // STICKS and msgs and blocks and images if (m.public_type == 0 || m.public_type == 20 || m.public_type == 21 || m.public_type > 50) { // normal message if (Settings.MAXPUBLICMSGS < publicMsgsLoaded || Settings.lightClient) { // if (!soutedPublicMsgsMax) { // System.out.println("Public msgs: " + // publicMsgsLoaded + " MAX: " + Settings.MAXPUBLICMSGS); // soutedPublicMsgsMax = true; // } if (m.getChannel() == null) { // isPublic... if (Settings.SUPERNODE) { p.getPendingMessagesPublic().put(messageId, m); } synchronized (p.getPendingMessages()) { p.getPendingMessages().remove(messageId); } continue; } } requestedMsgsLock.lock(); // Checke ob schon geladen wird und ueberpruefe timeout, falls peer zu langsam, // disconnected... if (requestedMsgs.contains(asEntryMsg)) { // ToDo: lock for requestedMsgs ? not threadsafe currently, exception will be // cautch = restart of loop (hack) RawMsgEntry get = requestedMsgs.get(requestedMsgs.indexOf(asEntryMsg)); long delay = System.currentTimeMillis() - get.requestedWhen; Log.put("delay: " + delay + " ip: " + get.requestedFromPeer.getIp(), 15); if (delay < 20000L) { requestedMsgsLock.unlock(); continue; } // if (delay > Settings.pingTimeout * 1000L + 60000L) { if (delay > 240000L) { System.out.println("MSG hard timeout... " + get.requestedFromPeer.getIp()); requestedMsgs.remove(get); get.requestedFromPeer.getPendingMessagesTimedOut().put(messageId, get.m); get.requestedFromPeer.getPendingMessages().remove(messageId); // ToDo: timeout for timeoutmessages } else // System.out.println("MSG soft timeout... just requesting at another // peer"); { if (get.requestedFromPeer == p) { // System.out.println("softtimeout, but already requested from this peer... " // + p.nonce); System.out.print(":" + delay + ":"); requestedMsgsLock.unlock(); continue; } } } // System.out.println("u23zu323"); if (!p.isConnected() || !p.isAuthed()) { System.out.println("break1243!!"); break; } requestedOne = true; // Nachricht soll geladen werden requestedMsgs.add(asEntryMsg); requestedMsgsLock.unlock(); asEntryMsg.requestedWhen = System.currentTimeMillis(); asEntryMsg.requestedFromPeer = p; // ByteBuffer writeBuffer = p.writeBuffer; p.writeBufferLock.lock(); if (p.writeBuffer == null) { p.writeBufferLock.unlock(); continue; } p.writeBuffer.put((byte) 6); p.writeBuffer.putInt(messageId); p.writeBufferLock.unlock(); Thread.interrupted(); p.setWriteBufferFilled(); if (Thread.interrupted()) { System.out.println("bd2n8xnrgm63734r9mt34y349qx5qn5qn935nxc69q56t"); } msgsRequestedThisCycle++; Log.put(" " + p.requestedMsgs + " (" + p.ip + "-" + messageId + ") ", 0); // System.out.println("requested... " + p.requestedMsgs); // // System.out.println("Nachricht download: " + p.ip + ":" + // p.port + " MsgTimestamp: " + m.timestamp + " Requested: " + p.requestedMsgs); p.requestedMsgs++; if (p.requestedMsgs > MAX_REQUEST_PER_PEER || p.requestedMsgs > p.maxSimultaneousRequests) { break; } } else if (m.public_type == 1) { synchronized (p.getPendingMessages()) { p.getPendingMessages().remove(messageId); } // found a stick... // checking difficulty Stick stick = new Stick(m.getKey().getPubKey(), m.timestamp, m.nonce); double difficulty = stick.getDifficulty(); if (difficulty < Stick.DIFFICULTY) { System.out.println("Stick is invalid, not enough difficulty..."); } else { System.out.println("Stick found: " + difficulty); m.verified = true; RawMsg addMessage = MessageHolder.addMessage(m); Test.broadcastMsg(addMessage); Test.messageStore.addStick( m.key.database_id, messageId, difficulty, m.timestamp + 1000 * 60 * 60 * 24 * 7); } } else if (m.public_type == 15) { // remove all msgs from that chan that are older then this message with // public type 20 or greater 50 // removeMessagesFromChannel // TODO WRONG PLACE HERE! implement in ConnectionHandler! } else { System.out.println("Message type not defined.... " + m.public_type); } } } if (!triggered) { syncInterrupt.lock(); allowInterrupt = true; syncInterrupt.unlock(); try { // System.out.println("wait"); if (shortWait) { sleep(500); } else { sleep(1000 * 60 * 5); } } catch (InterruptedException ex) { } syncInterrupt.lock(); allowInterrupt = false; syncInterrupt.unlock(); } // sleep, so we can wait for others nodes to introduce the same message (this reduces CPU // usage, but delays messages a bit) if (WAIT_FOR_OTHER_NODES_TO_INTRODUCE != 0) { try { sleep(WAIT_FOR_OTHER_NODES_TO_INTRODUCE); } catch (InterruptedException ex) { } } // clear interrupted flag, might called twice, so writeBuffer would think it was // interrupted... interrupted(); // Keine nachricht zum requesten, warte auf neue Nachricht, bzw timeout checken // if (!requestedOne) { // while (!triggered) { // try { // sleep(1000 * 5); // } catch (InterruptedException ex) { // } // // //muss timeout geprueft werden? //// if (!requestedMsgs.isEmpty()) { //// break; //// } // // // // } // // } } catch (Throwable e) { Test.sendStacktrace("SLEEP ! catched msg downloader exc.: \n", e); System.out.println("MessageDownloader exception!!!!: "); e.printStackTrace(); try { sleep(60000); } catch (InterruptedException ex) { } } } }