Improved connection management, preventing multiple connections to the same node, and improved broadcast handling.
This commit is contained in:
@ -27,6 +27,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static ch.dissem.bitmessage.entity.Plaintext.Status.*;
|
||||
@ -109,7 +110,6 @@ class DefaultMessageListener implements NetworkHandler.MessageListener {
|
||||
ctx.getAddressRepo().save(address);
|
||||
}
|
||||
} catch (DecryptionFailedException ignore) {
|
||||
LOG.debug(ignore.getMessage(), ignore);
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,21 +129,25 @@ class DefaultMessageListener implements NetworkHandler.MessageListener {
|
||||
}
|
||||
break;
|
||||
} catch (DecryptionFailedException ignore) {
|
||||
LOG.trace(ignore.getMessage(), ignore);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void receive(ObjectMessage object, Broadcast broadcast) throws IOException {
|
||||
// TODO this should work fine as-is, but checking the tag might be more efficient
|
||||
// V5Broadcast v5 = broadcast instanceof V5Broadcast ? (V5Broadcast) broadcast : null;
|
||||
for (BitmessageAddress subscription : ctx.getAddressRepo().getSubscriptions()) {
|
||||
byte[] tag = broadcast instanceof V5Broadcast ? ((V5Broadcast) broadcast).getTag() : null;
|
||||
for (BitmessageAddress subscription : ctx.getAddressRepo().getSubscriptions(broadcast.getVersion())) {
|
||||
if (tag != null && !Arrays.equals(tag, subscription.getTag())) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
broadcast.decrypt(subscription.getPublicDecryptionKey());
|
||||
if (!object.isSignatureValid(broadcast.getPlaintext().getFrom().getPubkey())) {
|
||||
LOG.warn("Broadcast with IV " + object.getInventoryVector() + " was successfully decrypted, but signature check failed. Ignoring.");
|
||||
} else {
|
||||
broadcast.getPlaintext().setStatus(RECEIVED);
|
||||
broadcast.getPlaintext().addLabels(ctx.getMessageRepository().getLabels(Label.Type.INBOX, Label.Type.UNREAD));
|
||||
broadcast.getPlaintext().setInventoryVector(object.getInventoryVector());
|
||||
ctx.getMessageRepository().save(broadcast.getPlaintext());
|
||||
listener.receive(broadcast.getPlaintext());
|
||||
}
|
||||
} catch (DecryptionFailedException ignore) {
|
||||
|
@ -31,6 +31,9 @@ public interface AddressRepository {
|
||||
List<BitmessageAddress> getIdentities();
|
||||
|
||||
List<BitmessageAddress> getSubscriptions();
|
||||
|
||||
List<BitmessageAddress> getSubscriptions(long broadcastVersion);
|
||||
|
||||
/**
|
||||
* Returns all Bitmessage addresses that have no private key.
|
||||
*/
|
||||
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2015 Christian Basler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package ch.dissem.bitmessage.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
public class Collections {
|
||||
private final static Random RANDOM = new Random();
|
||||
|
||||
/**
|
||||
* Returns a random subset of the given collection, or a copy of the collection if it's not larger than count.
|
||||
* The randomness
|
||||
*/
|
||||
public static <T> List<T> selectRandom(int count, Collection<T> collection) {
|
||||
ArrayList<T> result = new ArrayList<>(count);
|
||||
if (collection.size() <= count) {
|
||||
result.addAll(collection);
|
||||
} else {
|
||||
double collectionRest = collection.size();
|
||||
double resultRest = count;
|
||||
int skipMax = (int) Math.ceil(collectionRest / resultRest);
|
||||
int skip = RANDOM.nextInt(skipMax);
|
||||
for (T item : collection) {
|
||||
collectionRest--;
|
||||
if (skip > 0) {
|
||||
skip--;
|
||||
} else {
|
||||
result.add(item);
|
||||
resultRest--;
|
||||
if (resultRest == 0){
|
||||
break;
|
||||
}
|
||||
skipMax = (int) Math.ceil(collectionRest / resultRest);
|
||||
skip = RANDOM.nextInt(skipMax);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2015 Christian Basler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package ch.dissem.bitmessage.utils;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class CollectionsTest {
|
||||
@Test
|
||||
public void ensureSelectRandomReturnsMaximumPossibleItems() throws Exception {
|
||||
List<Integer> list = new LinkedList<>();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
list.add(i);
|
||||
}
|
||||
assertEquals(9, Collections.selectRandom(9, list).size());
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user