From f89d1a342ed3d596bae43c7c4ac08d47de6e88ca Mon Sep 17 00:00:00 2001 From: Christian Basler Date: Fri, 28 Aug 2015 13:48:01 +0200 Subject: [PATCH] Fixed a few problems: - some bugs that creeped in when I moved security into its own adapter - improved some DB code as it doesn't work in Android anyway - all entities should be serializable (very useful in Android) --- demo/build.gradle | 2 ++ .../dissem/bitmessage/demo/Application.java | 3 ++ .../java/ch/dissem/bitmessage/demo/Main.java | 3 ++ .../ch/dissem/bitmessage/InternalContext.java | 2 +- .../dissem/bitmessage/entity/Plaintext.java | 14 +++++++-- .../dissem/bitmessage/entity/Streamable.java | 5 ++-- .../entity/payload/ObjectPayload.java | 1 + .../bitmessage/entity/valueobject/Label.java | 3 +- .../bitmessage/ports}/MemoryNodeRegistry.java | 3 +- .../bitmessage/ports/NetworkHandler.java | 3 ++ .../ch/dissem/bitmessage/utils/Bytes.java | 8 ++--- .../ch/dissem/bitmessage/utils/Encode.java | 2 ++ .../src/main/resources/nodes.txt | 0 .../bitmessage/entity/SerializationTest.java | 29 +++++++++++++++---- .../networking/DefaultNetworkHandler.java | 6 ++++ .../repository/JdbcAddressRepository.java | 15 +++++----- .../bitmessage/repository/JdbcHelper.java | 4 +-- .../bitmessage/repository/JdbcInventory.java | 9 +++--- .../repository/JdbcMessageRepository.java | 8 +++-- .../repository/JdbcNodeRegistryTest.java | 1 + 20 files changed, 83 insertions(+), 38 deletions(-) rename {repositories/src/main/java/ch/dissem/bitmessage/repository => domain/src/main/java/ch/dissem/bitmessage/ports}/MemoryNodeRegistry.java (98%) rename {repositories => domain}/src/main/resources/nodes.txt (100%) diff --git a/demo/build.gradle b/demo/build.gradle index 8d6414c..cba7d93 100644 --- a/demo/build.gradle +++ b/demo/build.gradle @@ -22,8 +22,10 @@ dependencies { compile project(':domain') compile project(':networking') compile project(':repositories') + compile project(':security-bc') compile project(':wif') compile 'org.slf4j:slf4j-simple:1.7.12' compile 'args4j:args4j:2.32' + compile 'com.h2database:h2:1.4.187' testCompile 'junit:junit:4.11' } diff --git a/demo/src/main/java/ch/dissem/bitmessage/demo/Application.java b/demo/src/main/java/ch/dissem/bitmessage/demo/Application.java index 416e7b7..2f6f9fd 100644 --- a/demo/src/main/java/ch/dissem/bitmessage/demo/Application.java +++ b/demo/src/main/java/ch/dissem/bitmessage/demo/Application.java @@ -21,7 +21,9 @@ import ch.dissem.bitmessage.entity.BitmessageAddress; import ch.dissem.bitmessage.entity.Plaintext; import ch.dissem.bitmessage.entity.payload.Pubkey; import ch.dissem.bitmessage.networking.DefaultNetworkHandler; +import ch.dissem.bitmessage.ports.MemoryNodeRegistry; import ch.dissem.bitmessage.repository.*; +import ch.dissem.bitmessage.security.bc.BouncySecurity; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,6 +48,7 @@ public class Application { .nodeRegistry(new MemoryNodeRegistry()) .messageRepo(new JdbcMessageRepository(jdbcConfig)) .networkHandler(new DefaultNetworkHandler()) + .security(new BouncySecurity()) .port(48444) .build(); diff --git a/demo/src/main/java/ch/dissem/bitmessage/demo/Main.java b/demo/src/main/java/ch/dissem/bitmessage/demo/Main.java index 7f934a3..ac90e88 100644 --- a/demo/src/main/java/ch/dissem/bitmessage/demo/Main.java +++ b/demo/src/main/java/ch/dissem/bitmessage/demo/Main.java @@ -18,7 +18,9 @@ package ch.dissem.bitmessage.demo; import ch.dissem.bitmessage.BitmessageContext; import ch.dissem.bitmessage.networking.DefaultNetworkHandler; +import ch.dissem.bitmessage.ports.MemoryNodeRegistry; import ch.dissem.bitmessage.repository.*; +import ch.dissem.bitmessage.security.bc.BouncySecurity; import ch.dissem.bitmessage.wif.WifExporter; import ch.dissem.bitmessage.wif.WifImporter; import org.kohsuke.args4j.CmdLineException; @@ -50,6 +52,7 @@ public class Main { .nodeRegistry(new MemoryNodeRegistry()) .messageRepo(new JdbcMessageRepository(jdbcConfig)) .networkHandler(new DefaultNetworkHandler()) + .security(new BouncySecurity()) .port(48444) .build(); diff --git a/domain/src/main/java/ch/dissem/bitmessage/InternalContext.java b/domain/src/main/java/ch/dissem/bitmessage/InternalContext.java index 03fef80..05ccd51 100644 --- a/domain/src/main/java/ch/dissem/bitmessage/InternalContext.java +++ b/domain/src/main/java/ch/dissem/bitmessage/InternalContext.java @@ -81,7 +81,7 @@ public class InternalContext { streams.add(1L); } - init(inventory, nodeRegistry, networkHandler, addressRepository, messageRepository, proofOfWorkEngine); + init(inventory, nodeRegistry, networkHandler, addressRepository, messageRepository, proofOfWorkEngine, security); } private void init(Object... objects) { diff --git a/domain/src/main/java/ch/dissem/bitmessage/entity/Plaintext.java b/domain/src/main/java/ch/dissem/bitmessage/entity/Plaintext.java index e73849f..eb0a60f 100644 --- a/domain/src/main/java/ch/dissem/bitmessage/entity/Plaintext.java +++ b/domain/src/main/java/ch/dissem/bitmessage/entity/Plaintext.java @@ -19,9 +19,9 @@ package ch.dissem.bitmessage.entity; import ch.dissem.bitmessage.entity.valueobject.InventoryVector; import ch.dissem.bitmessage.entity.valueobject.Label; import ch.dissem.bitmessage.factory.Factory; -import ch.dissem.bitmessage.ports.Security; import ch.dissem.bitmessage.utils.Decode; import ch.dissem.bitmessage.utils.Encode; +import ch.dissem.bitmessage.utils.UnixTime; import java.io.*; import java.util.*; @@ -29,7 +29,7 @@ import java.util.*; /** * The unencrypted message to be sent by 'msg' or 'broadcast'. */ -public class Plaintext implements Streamable, Serializable { +public class Plaintext implements Streamable { private final Type type; private final BitmessageAddress from; private final long encoding; @@ -64,6 +64,7 @@ public class Plaintext implements Streamable, Serializable { public static Plaintext read(Type type, InputStream in) throws IOException { return readWithoutSignature(type, in) .signature(Decode.varBytes(in)) + .received(UnixTime.now()) .build(); } @@ -132,6 +133,15 @@ public class Plaintext implements Streamable, Serializable { this.signature = signature; } + public boolean isUnread() { + for (Label label : labels) { + if (label.getType() == Label.Type.UNREAD) { + return true; + } + } + return false; + } + public void write(OutputStream out, boolean includeSignature) throws IOException { Encode.varInt(from.getVersion(), out); Encode.varInt(from.getStream(), out); diff --git a/domain/src/main/java/ch/dissem/bitmessage/entity/Streamable.java b/domain/src/main/java/ch/dissem/bitmessage/entity/Streamable.java index 0601a44..cc12050 100644 --- a/domain/src/main/java/ch/dissem/bitmessage/entity/Streamable.java +++ b/domain/src/main/java/ch/dissem/bitmessage/entity/Streamable.java @@ -16,14 +16,13 @@ package ch.dissem.bitmessage.entity; -import ch.dissem.bitmessage.ports.Security; - import java.io.IOException; import java.io.OutputStream; +import java.io.Serializable; /** * An object that can be written to an {@link OutputStream} */ -public interface Streamable { +public interface Streamable extends Serializable { void write(OutputStream stream) throws IOException; } diff --git a/domain/src/main/java/ch/dissem/bitmessage/entity/payload/ObjectPayload.java b/domain/src/main/java/ch/dissem/bitmessage/entity/payload/ObjectPayload.java index ef42718..0ca45cd 100644 --- a/domain/src/main/java/ch/dissem/bitmessage/entity/payload/ObjectPayload.java +++ b/domain/src/main/java/ch/dissem/bitmessage/entity/payload/ObjectPayload.java @@ -21,6 +21,7 @@ import ch.dissem.bitmessage.entity.Streamable; import java.io.IOException; import java.io.OutputStream; +import java.io.Serializable; /** * The payload of an 'object' command. This is shared by the network. diff --git a/domain/src/main/java/ch/dissem/bitmessage/entity/valueobject/Label.java b/domain/src/main/java/ch/dissem/bitmessage/entity/valueobject/Label.java index e1bd8f2..7c37973 100644 --- a/domain/src/main/java/ch/dissem/bitmessage/entity/valueobject/Label.java +++ b/domain/src/main/java/ch/dissem/bitmessage/entity/valueobject/Label.java @@ -16,9 +16,10 @@ package ch.dissem.bitmessage.entity.valueobject; +import java.io.Serializable; import java.util.Objects; -public class Label { +public class Label implements Serializable { private Object id; private String label; private Type type; diff --git a/repositories/src/main/java/ch/dissem/bitmessage/repository/MemoryNodeRegistry.java b/domain/src/main/java/ch/dissem/bitmessage/ports/MemoryNodeRegistry.java similarity index 98% rename from repositories/src/main/java/ch/dissem/bitmessage/repository/MemoryNodeRegistry.java rename to domain/src/main/java/ch/dissem/bitmessage/ports/MemoryNodeRegistry.java index 15a4134..04fa2f9 100644 --- a/repositories/src/main/java/ch/dissem/bitmessage/repository/MemoryNodeRegistry.java +++ b/domain/src/main/java/ch/dissem/bitmessage/ports/MemoryNodeRegistry.java @@ -14,10 +14,9 @@ * limitations under the License. */ -package ch.dissem.bitmessage.repository; +package ch.dissem.bitmessage.ports; import ch.dissem.bitmessage.entity.valueobject.NetworkAddress; -import ch.dissem.bitmessage.ports.NodeRegistry; import ch.dissem.bitmessage.utils.UnixTime; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/domain/src/main/java/ch/dissem/bitmessage/ports/NetworkHandler.java b/domain/src/main/java/ch/dissem/bitmessage/ports/NetworkHandler.java index 4b73629..e07bd79 100644 --- a/domain/src/main/java/ch/dissem/bitmessage/ports/NetworkHandler.java +++ b/domain/src/main/java/ch/dissem/bitmessage/ports/NetworkHandler.java @@ -21,6 +21,7 @@ import ch.dissem.bitmessage.entity.valueobject.InventoryVector; import ch.dissem.bitmessage.utils.Property; import java.io.IOException; +import java.net.InetAddress; /** * Handles incoming messages @@ -30,6 +31,8 @@ public interface NetworkHandler { void stop(); + void synchronize(InetAddress trustedHost, int port, MessageListener listener) throws IOException; + void offer(InventoryVector iv); Property getNetworkStatus(); diff --git a/domain/src/main/java/ch/dissem/bitmessage/utils/Bytes.java b/domain/src/main/java/ch/dissem/bitmessage/utils/Bytes.java index 31a3dcc..8107eb0 100644 --- a/domain/src/main/java/ch/dissem/bitmessage/utils/Bytes.java +++ b/domain/src/main/java/ch/dissem/bitmessage/utils/Bytes.java @@ -16,12 +16,6 @@ package ch.dissem.bitmessage.utils; -import ch.dissem.bitmessage.entity.Streamable; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.Arrays; - /** * A helper class for working with byte arrays interpreted as unsigned big endian integers. * This is one part due to the fact that Java doesn't support unsigned numbers, and another @@ -91,6 +85,8 @@ public class Bytes { if (a < 0) return b < 0 && a < b; if (b < 0) return a >= 0 || a < b; return a < b; + // This would be easier to understand, but is (slightly) slower: + // return (a & 0xff) < (b & 0xff); } /** diff --git a/domain/src/main/java/ch/dissem/bitmessage/utils/Encode.java b/domain/src/main/java/ch/dissem/bitmessage/utils/Encode.java index 095fb78..a78d03f 100644 --- a/domain/src/main/java/ch/dissem/bitmessage/utils/Encode.java +++ b/domain/src/main/java/ch/dissem/bitmessage/utils/Encode.java @@ -117,6 +117,8 @@ public class Encode { * @throws IOException if an I/O error occurs. */ public static byte[] bytes(Streamable streamable) throws IOException { + if (streamable == null) return null; + ByteArrayOutputStream stream = new ByteArrayOutputStream(); streamable.write(stream); return stream.toByteArray(); diff --git a/repositories/src/main/resources/nodes.txt b/domain/src/main/resources/nodes.txt similarity index 100% rename from repositories/src/main/resources/nodes.txt rename to domain/src/main/resources/nodes.txt diff --git a/domain/src/test/java/ch/dissem/bitmessage/entity/SerializationTest.java b/domain/src/test/java/ch/dissem/bitmessage/entity/SerializationTest.java index 7e56f95..de0c807 100644 --- a/domain/src/test/java/ch/dissem/bitmessage/entity/SerializationTest.java +++ b/domain/src/test/java/ch/dissem/bitmessage/entity/SerializationTest.java @@ -17,21 +17,21 @@ package ch.dissem.bitmessage.entity; import ch.dissem.bitmessage.entity.payload.*; +import ch.dissem.bitmessage.entity.valueobject.Label; import ch.dissem.bitmessage.exception.DecryptionFailedException; import ch.dissem.bitmessage.factory.Factory; +import ch.dissem.bitmessage.utils.TestBase; import ch.dissem.bitmessage.utils.TestUtils; import org.junit.Test; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; +import java.util.Arrays; import static ch.dissem.bitmessage.entity.Plaintext.Type.MSG; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; -public class SerializationTest { +public class SerializationTest extends TestBase { @Test public void ensureGetPubkeyIsDeserializedAndSerializedCorrectly() throws IOException { doTest("V2GetPubkey.payload", 2, GetPubkey.class); @@ -75,7 +75,7 @@ public class SerializationTest { } @Test - public void ensurePlaintextIsSerializedAndDeserializedCorrectly() throws IOException, DecryptionFailedException { + public void ensurePlaintextIsSerializedAndDeserializedCorrectly() throws Exception { Plaintext p1 = new Plaintext.Builder(MSG) .from(TestUtils.loadIdentity("BM-2cSqjfJ8xK6UUn5Rw3RpdGQ9RsDkBhWnS8")) .to(TestUtils.loadContact()) @@ -99,4 +99,21 @@ public class SerializationTest { assertArrayEquals(data, out.toByteArray()); assertEquals(expectedPayloadType.getCanonicalName(), object.getPayload().getClass().getCanonicalName()); } + + @Test + public void ensureSystemSerializationWorks() throws Exception { + Plaintext plaintext = new Plaintext.Builder(MSG) + .from(TestUtils.loadContact()) + .to(TestUtils.loadIdentity("BM-2cSqjfJ8xK6UUn5Rw3RpdGQ9RsDkBhWnS8")) + .labels(Arrays.asList(new Label("Test", Label.Type.INBOX, 0))) + .message("Test", "Test Test.\nTest") + .build(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(out); + oos.writeObject(plaintext); + + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + ObjectInputStream ois = new ObjectInputStream(in); + assertEquals(plaintext, ois.readObject()); + } } diff --git a/networking/src/main/java/ch/dissem/bitmessage/networking/DefaultNetworkHandler.java b/networking/src/main/java/ch/dissem/bitmessage/networking/DefaultNetworkHandler.java index 558d097..e73e8ed 100644 --- a/networking/src/main/java/ch/dissem/bitmessage/networking/DefaultNetworkHandler.java +++ b/networking/src/main/java/ch/dissem/bitmessage/networking/DefaultNetworkHandler.java @@ -27,6 +27,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; +import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.util.*; @@ -149,6 +150,11 @@ public class DefaultNetworkHandler implements NetworkHandler, ContextHolder { } } + @Override + public void synchronize(InetAddress trustedHost, int port, MessageListener listener) throws IOException { + startConnection(new Connection(ctx, CLIENT, new Socket(trustedHost, port), listener, requestedObjects)); + } + private void startConnection(Connection c) { synchronized (connections) { // prevent connecting twice to the same node diff --git a/repositories/src/main/java/ch/dissem/bitmessage/repository/JdbcAddressRepository.java b/repositories/src/main/java/ch/dissem/bitmessage/repository/JdbcAddressRepository.java index 099690d..337d50a 100644 --- a/repositories/src/main/java/ch/dissem/bitmessage/repository/JdbcAddressRepository.java +++ b/repositories/src/main/java/ch/dissem/bitmessage/repository/JdbcAddressRepository.java @@ -29,6 +29,7 @@ import org.slf4j.LoggerFactory; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; import java.sql.*; import java.util.Arrays; import java.util.LinkedList; @@ -97,16 +98,16 @@ public class JdbcAddressRepository extends JdbcHelper implements AddressReposito while (rs.next()) { BitmessageAddress address; - byte[] privateKeyBytes = rs.getBytes("private_key"); - if (privateKeyBytes != null) { - PrivateKey privateKey = PrivateKey.read(new ByteArrayInputStream(privateKeyBytes)); + InputStream privateKeyStream = rs.getBinaryStream("private_key"); + if (privateKeyStream != null) { + PrivateKey privateKey = PrivateKey.read(privateKeyStream); address = new BitmessageAddress(privateKey); } else { address = new BitmessageAddress(rs.getString("address")); - byte[] publicKeyBytes = rs.getBytes("public_key"); - if (publicKeyBytes != null) { + Blob publicKeyBlob = rs.getBlob("public_key"); + if (publicKeyBlob != null) { Pubkey pubkey = Factory.readPubkey(address.getVersion(), address.getStream(), - new ByteArrayInputStream(publicKeyBytes), publicKeyBytes.length, false); + publicKeyBlob.getBinaryStream(), (int) publicKeyBlob.length(), false); if (address.getVersion() == 4 && pubkey instanceof V3Pubkey) { pubkey = new V4Pubkey((V3Pubkey) pubkey); } @@ -182,7 +183,7 @@ public class JdbcAddressRepository extends JdbcHelper implements AddressReposito data.writeUnencrypted(out); ps.setBytes(parameterIndex, out.toByteArray()); } else { - ps.setBlob(parameterIndex, (Blob) null); + ps.setBytes(parameterIndex, null); } } diff --git a/repositories/src/main/java/ch/dissem/bitmessage/repository/JdbcHelper.java b/repositories/src/main/java/ch/dissem/bitmessage/repository/JdbcHelper.java index b6e7461..601ce29 100644 --- a/repositories/src/main/java/ch/dissem/bitmessage/repository/JdbcHelper.java +++ b/repositories/src/main/java/ch/dissem/bitmessage/repository/JdbcHelper.java @@ -21,10 +21,8 @@ import ch.dissem.bitmessage.entity.payload.ObjectType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.sql.Blob; import java.sql.PreparedStatement; import java.sql.SQLException; @@ -84,7 +82,7 @@ abstract class JdbcHelper { data.write(os); ps.setBytes(parameterIndex, os.toByteArray()); } else { - ps.setBlob(parameterIndex, (Blob) null); + ps.setBytes(parameterIndex, null); } } } diff --git a/repositories/src/main/java/ch/dissem/bitmessage/repository/JdbcInventory.java b/repositories/src/main/java/ch/dissem/bitmessage/repository/JdbcInventory.java index 6a9e35c..98034ee 100644 --- a/repositories/src/main/java/ch/dissem/bitmessage/repository/JdbcInventory.java +++ b/repositories/src/main/java/ch/dissem/bitmessage/repository/JdbcInventory.java @@ -53,6 +53,7 @@ public class JdbcInventory extends JdbcHelper implements Inventory { } return result; } + private List getFullInventory(long... streams) { List result = new LinkedList<>(); try (Connection connection = config.getConnection()) { @@ -79,8 +80,8 @@ public class JdbcInventory extends JdbcHelper implements Inventory { Statement stmt = connection.createStatement(); ResultSet rs = stmt.executeQuery("SELECT data, version FROM Inventory WHERE hash = X'" + vector + "'"); if (rs.next()) { - byte[] data = rs.getBytes("data"); - return Factory.getObjectMessage(rs.getInt("version"), new ByteArrayInputStream(data), data.length); + Blob data = rs.getBlob("data"); + return Factory.getObjectMessage(rs.getInt("version"), data.getBinaryStream(), (int) data.length()); } else { LOG.info("Object requested that we don't have. IV: " + vector); return null; @@ -108,8 +109,8 @@ public class JdbcInventory extends JdbcHelper implements Inventory { ResultSet rs = stmt.executeQuery(query.toString()); List result = new LinkedList<>(); while (rs.next()) { - byte[] data = rs.getBytes("data"); - result.add(Factory.getObjectMessage(rs.getInt("version"), new ByteArrayInputStream(data), data.length)); + Blob data = rs.getBlob("data"); + result.add(Factory.getObjectMessage(rs.getInt("version"), data.getBinaryStream(), (int) data.length())); } return result; } catch (Exception e) { diff --git a/repositories/src/main/java/ch/dissem/bitmessage/repository/JdbcMessageRepository.java b/repositories/src/main/java/ch/dissem/bitmessage/repository/JdbcMessageRepository.java index a2476e5..ec89e68 100644 --- a/repositories/src/main/java/ch/dissem/bitmessage/repository/JdbcMessageRepository.java +++ b/repositories/src/main/java/ch/dissem/bitmessage/repository/JdbcMessageRepository.java @@ -27,6 +27,7 @@ import org.slf4j.LoggerFactory; import java.io.ByteArrayInputStream; import java.io.IOException; +import java.io.InputStream; import java.sql.*; import java.util.ArrayList; import java.util.Collection; @@ -107,9 +108,9 @@ public class JdbcMessageRepository extends JdbcHelper implements MessageReposito ResultSet rs = stmt.executeQuery("SELECT id, iv, type, sender, recipient, data, sent, received, status FROM Message WHERE " + where); while (rs.next()) { byte[] iv = rs.getBytes("iv"); - byte[] data = rs.getBytes("data"); + InputStream data = rs.getBinaryStream("data"); Plaintext.Type type = Plaintext.Type.valueOf(rs.getString("type")); - Plaintext.Builder builder = Plaintext.readWithoutSignature(type, new ByteArrayInputStream(data)); + Plaintext.Builder builder = Plaintext.readWithoutSignature(type, data); long id = rs.getLong("id"); builder.id(id); builder.IV(new InventoryVector(iv)); @@ -191,7 +192,8 @@ public class JdbcMessageRepository extends JdbcHelper implements MessageReposito private void insert(Connection connection, Plaintext message) throws SQLException, IOException { PreparedStatement ps = connection.prepareStatement( - "INSERT INTO Message (iv, type, sender, recipient, data, sent, received, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS); + "INSERT INTO Message (iv, type, sender, recipient, data, sent, received, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", + Statement.RETURN_GENERATED_KEYS); ps.setBytes(1, message.getInventoryVector() != null ? message.getInventoryVector().getHash() : null); ps.setString(2, message.getType().name()); ps.setString(3, message.getFrom().getAddress()); diff --git a/repositories/src/test/java/ch/dissem/bitmessage/repository/JdbcNodeRegistryTest.java b/repositories/src/test/java/ch/dissem/bitmessage/repository/JdbcNodeRegistryTest.java index ca4bcd7..044c44c 100644 --- a/repositories/src/test/java/ch/dissem/bitmessage/repository/JdbcNodeRegistryTest.java +++ b/repositories/src/test/java/ch/dissem/bitmessage/repository/JdbcNodeRegistryTest.java @@ -17,6 +17,7 @@ package ch.dissem.bitmessage.repository; import ch.dissem.bitmessage.entity.valueobject.NetworkAddress; +import ch.dissem.bitmessage.ports.MemoryNodeRegistry; import ch.dissem.bitmessage.ports.NodeRegistry; import org.junit.Before; import org.junit.Test;