package network.thunder.core.communication.processor.implementations; import network.thunder.core.communication.Message; import network.thunder.core.communication.objects.messages.MessageExecutor; import network.thunder.core.communication.objects.messages.impl.message.gossip.objects.P2PDataObject; import network.thunder.core.communication.objects.messages.impl.message.gossip.objects.PubkeyIPObject; import network.thunder.core.communication.objects.messages.impl.message.peerseed.PeerSeedGetMessage; import network.thunder.core.communication.objects.messages.impl.message.peerseed.PeerSeedSendMessage; import network.thunder.core.communication.objects.messages.impl.results.PeerSeedResult; import network.thunder.core.communication.objects.messages.interfaces.factories.ContextFactory; import network.thunder.core.communication.objects.messages.interfaces.factories.PeerSeedMessageFactory; import network.thunder.core.communication.objects.messages.interfaces.helper.LNEventHelper; import network.thunder.core.communication.objects.messages.interfaces.message.peerseed.PeerSeedMessage; import network.thunder.core.communication.processor.ChannelIntent; import network.thunder.core.communication.processor.interfaces.PeerSeedProcessor; import network.thunder.core.database.DBHandler; import network.thunder.core.etc.Tools; import network.thunder.core.mesh.NodeClient; import network.thunder.core.mesh.NodeServer; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * Created by matsjerratsch on 22/01/2016. */ public class PeerSeedProcessorImpl extends PeerSeedProcessor { DBHandler dbHandler; NodeClient node; NodeServer nodeServer; PeerSeedMessageFactory messageFactory; LNEventHelper eventHelper; MessageExecutor messageExecutor; public PeerSeedProcessorImpl (ContextFactory contextFactory, DBHandler dbHandler, NodeClient node) { this.messageFactory = contextFactory.getPeerSeedMessageFactory(); this.dbHandler = dbHandler; this.eventHelper = contextFactory.getEventHelper(); this.node = node; this.nodeServer = contextFactory.getServerSettings(); } @Override public void onInboundMessage (Message message) { consumeMessage((PeerSeedMessage) message); } @Override public boolean consumesInboundMessage (Object object) { return (object instanceof PeerSeedMessage); } @Override public boolean consumesOutboundMessage (Object object) { return false; } @Override public void onLayerActive (MessageExecutor messageExecutor) { this.messageExecutor = messageExecutor; if (node.isServer) { messageExecutor.sendNextLayerActive(); } else { if (node.intent == ChannelIntent.GET_IPS) { messageExecutor.sendMessageUpwards(messageFactory.getPeerSeedGetMessage()); } else { messageExecutor.sendNextLayerActive(); } } } private void consumeMessage (PeerSeedMessage message) { if (message instanceof PeerSeedGetMessage) { List<PubkeyIPObject> ipObjects = dbHandler.getIPObjects(); if (ipObjects.size() > PEERS_TO_SEND) { ipObjects = Tools.getRandomSubList(ipObjects, PEERS_TO_SEND); } Message response = messageFactory.getPeerSeedSendMessage(ipObjects); messageExecutor.sendMessageUpwards(response); } else if (message instanceof PeerSeedSendMessage) { PeerSeedSendMessage sendMessage = (PeerSeedSendMessage) message; List<PubkeyIPObject> list = removeOurIPFromList(sendMessage.ipObjectList); dbHandler.insertIPObjects(P2PDataObject.generaliseList(list)); fireIPEvents(list); //TODO We might always want to close here, given that we only ever get here if intent = GET_IPS if (!node.isServer && node.intent == ChannelIntent.GET_IPS) { node.resultCallback.execute(new PeerSeedResult()); messageExecutor.closeConnection(); } } } private void fireIPEvents (List<PubkeyIPObject> list) { for (PubkeyIPObject ip : list) { eventHelper.onReceivedIP(ip); } } private List<PubkeyIPObject> removeOurIPFromList (List<PubkeyIPObject> list) { List<PubkeyIPObject> toRemove = new ArrayList<>(); for (PubkeyIPObject ip : list) { if (Arrays.equals(ip.pubkey, nodeServer.pubKeyServer.getPubKey())) { toRemove.add(ip); } } list.removeAll(toRemove); return list; } }