From 2ac3bdd3aea9eace933cf05dc49a63bb3191a5e6 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Mon, 17 May 2021 16:23:54 +0100 Subject: [PATCH 1/2] Add database method for getting transports with keys. --- .../bramble/api/db/DatabaseComponent.java | 10 ++++++ .../org/briarproject/bramble/db/Database.java | 10 ++++++ .../bramble/db/DatabaseComponentImpl.java | 7 ++++ .../briarproject/bramble/db/JdbcDatabase.java | 32 +++++++++++++++++++ .../bramble/db/JdbcDatabaseTest.java | 6 ++++ 5 files changed, 65 insertions(+) diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/db/DatabaseComponent.java b/bramble-api/src/main/java/org/briarproject/bramble/api/db/DatabaseComponent.java index 3c79254d3..f95f493a3 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/db/DatabaseComponent.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/db/DatabaseComponent.java @@ -493,6 +493,16 @@ public interface DatabaseComponent extends TransactionManager { Collection getTransportKeys(Transaction txn, TransportId t) throws DbException; + /** + * Returns the contact IDs and transport IDs for which the DB contains + * at least one set of transport keys. Handshake mode and rotation mode + * keys are included, whether activated or not. + *

+ * Read-only. + */ + Map> getTransportsWithKeys( + Transaction txn) throws DbException; + /** * Increments the outgoing stream counter for the given transport keys. */ diff --git a/bramble-core/src/main/java/org/briarproject/bramble/db/Database.java b/bramble-core/src/main/java/org/briarproject/bramble/db/Database.java index ab291fa30..2744abe23 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/db/Database.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/db/Database.java @@ -590,6 +590,16 @@ interface Database { Collection getTransportKeys(T txn, TransportId t) throws DbException; + /** + * Returns the contact IDs and transport IDs for which the DB contains + * at least one set of transport keys. Handshake mode and rotation mode + * keys are included, whether activated or not. + *

+ * Read-only. + */ + Map> getTransportsWithKeys(T txn) + throws DbException; + /** * Increments the outgoing stream counter for the given transport keys. */ diff --git a/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseComponentImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseComponentImpl.java index 40ba6fa31..776f02c6f 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseComponentImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseComponentImpl.java @@ -780,6 +780,13 @@ class DatabaseComponentImpl implements DatabaseComponent { return db.getTransportKeys(txn, t); } + @Override + public Map> getTransportsWithKeys( + Transaction transaction) throws DbException { + T txn = unbox(transaction); + return db.getTransportsWithKeys(txn); + } + @Override public void incrementStreamCounter(Transaction transaction, TransportId t, KeySetId k) throws DbException { diff --git a/bramble-core/src/main/java/org/briarproject/bramble/db/JdbcDatabase.java b/bramble-core/src/main/java/org/briarproject/bramble/db/JdbcDatabase.java index af54d4e9d..43f604e73 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/db/JdbcDatabase.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/db/JdbcDatabase.java @@ -2605,6 +2605,38 @@ abstract class JdbcDatabase implements Database { } } + @Override + public Map> getTransportsWithKeys( + Connection txn) throws DbException { + Statement s = null; + ResultSet rs = null; + try { + String sql = "SELECT DISTINCT contactId, transportId" + + " FROM outgoingKeys"; + s = txn.createStatement(); + rs = s.executeQuery(sql); + Map> ids = new HashMap<>(); + while (rs.next()) { + ContactId c = new ContactId(rs.getInt(1)); + TransportId t = new TransportId(rs.getString(2)); + Collection transportIds = ids.get(c); + if (transportIds == null) { + transportIds = new ArrayList<>(); + ids.put(c, transportIds); + } + transportIds.add(t); + } + rs.close(); + s.close(); + return ids; + } catch (SQLException e) { + tryToClose(rs, LOG, WARNING); + tryToClose(s, LOG, WARNING); + tryToClose(s, LOG, WARNING); + throw new DbException(e); + } + } + @Override public void incrementStreamCounter(Connection txn, TransportId t, KeySetId k) throws DbException { diff --git a/bramble-core/src/test/java/org/briarproject/bramble/db/JdbcDatabaseTest.java b/bramble-core/src/test/java/org/briarproject/bramble/db/JdbcDatabaseTest.java index 69bc97671..9336bedd1 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/db/JdbcDatabaseTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/db/JdbcDatabaseTest.java @@ -699,6 +699,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { // Initially there should be no transport keys in the database assertEquals(emptyList(), db.getTransportKeys(txn, transportId)); + assertTrue(db.getTransportsWithKeys(txn).isEmpty()); // Add the contact, the transport and the transport keys db.addIdentity(txn, identity); @@ -721,6 +722,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { assertKeysEquals(keys1, ks.getKeys()); } } + assertEquals(singletonMap(contactId, singletonList(transportId)), + db.getTransportsWithKeys(txn)); // Update the transport keys TransportKeys updated = createTransportKeys(timePeriod + 1, active); @@ -743,10 +746,13 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { assertKeysEquals(updated1, ks.getKeys()); } } + assertEquals(singletonMap(contactId, singletonList(transportId)), + db.getTransportsWithKeys(txn)); // Removing the contact should remove the transport keys db.removeContact(txn, contactId); assertEquals(emptyList(), db.getTransportKeys(txn, transportId)); + assertTrue(db.getTransportsWithKeys(txn).isEmpty()); db.commitTransaction(txn); db.close(); From ee6f571c318adfac42c7dee1c7c0dcf851d7bd18 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Wed, 19 May 2021 10:42:17 +0100 Subject: [PATCH 2/2] Add a DB method for checking whether transport keys exist. --- .../bramble/api/db/DatabaseComponent.java | 10 ++++++++ .../org/briarproject/bramble/db/Database.java | 10 ++++++++ .../bramble/db/DatabaseComponentImpl.java | 7 ++++++ .../briarproject/bramble/db/JdbcDatabase.java | 23 +++++++++++++++++++ .../bramble/db/JdbcDatabaseTest.java | 4 ++++ 5 files changed, 54 insertions(+) diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/db/DatabaseComponent.java b/bramble-api/src/main/java/org/briarproject/bramble/api/db/DatabaseComponent.java index f95f493a3..2771302a2 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/db/DatabaseComponent.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/db/DatabaseComponent.java @@ -150,6 +150,16 @@ public interface DatabaseComponent extends TransactionManager { boolean containsPendingContact(Transaction txn, PendingContactId p) throws DbException; + /** + * Returns true if the database contains keys for communicating with the + * given contact over the given transport. Handshake mode and rotation mode + * keys are included, whether activated or not. + *

+ * Read-only. + */ + boolean containsTransportKeys(Transaction txn, ContactId c, TransportId t) + throws DbException; + /** * Deletes the message with the given ID. Unlike * {@link #removeMessage(Transaction, MessageId)}, the message ID, diff --git a/bramble-core/src/main/java/org/briarproject/bramble/db/Database.java b/bramble-core/src/main/java/org/briarproject/bramble/db/Database.java index 2744abe23..705913ee7 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/db/Database.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/db/Database.java @@ -215,6 +215,16 @@ interface Database { */ boolean containsTransport(T txn, TransportId t) throws DbException; + /** + * Returns true if the database contains keys for communicating with the + * given contact over the given transport. Handshake mode and rotation mode + * keys are included, whether activated or not. + *

+ * Read-only. + */ + boolean containsTransportKeys(T txn, ContactId c, TransportId t) + throws DbException; + /** * Returns true if the database contains the given message, the message is * shared, and the visibility of the message's group to the given contact diff --git a/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseComponentImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseComponentImpl.java index 776f02c6f..b2422f9bc 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseComponentImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseComponentImpl.java @@ -371,6 +371,13 @@ class DatabaseComponentImpl implements DatabaseComponent { return db.containsPendingContact(txn, p); } + @Override + public boolean containsTransportKeys(Transaction transaction, ContactId c, + TransportId t) throws DbException { + T txn = unbox(transaction); + return db.containsTransportKeys(txn, c, t); + } + @Override public void deleteMessage(Transaction transaction, MessageId m) throws DbException { diff --git a/bramble-core/src/main/java/org/briarproject/bramble/db/JdbcDatabase.java b/bramble-core/src/main/java/org/briarproject/bramble/db/JdbcDatabase.java index 43f604e73..224b20bf1 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/db/JdbcDatabase.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/db/JdbcDatabase.java @@ -1277,6 +1277,29 @@ abstract class JdbcDatabase implements Database { } } + @Override + public boolean containsTransportKeys(Connection txn, ContactId c, + TransportId t) throws DbException { + PreparedStatement ps = null; + ResultSet rs = null; + try { + String sql = "SELECT NULL FROM outgoingKeys" + + " WHERE contactId = ? AND transportId = ?"; + ps = txn.prepareStatement(sql); + ps.setInt(1, c.getInt()); + ps.setString(2, t.getString()); + rs = ps.executeQuery(); + boolean found = rs.next(); + rs.close(); + ps.close(); + return found; + } catch (SQLException e) { + tryToClose(rs, LOG, WARNING); + tryToClose(ps, LOG, WARNING); + throw new DbException(e); + } + } + @Override public boolean containsVisibleMessage(Connection txn, ContactId c, MessageId m) throws DbException { diff --git a/bramble-core/src/test/java/org/briarproject/bramble/db/JdbcDatabaseTest.java b/bramble-core/src/test/java/org/briarproject/bramble/db/JdbcDatabaseTest.java index 9336bedd1..2da33c18d 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/db/JdbcDatabaseTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/db/JdbcDatabaseTest.java @@ -698,6 +698,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Initially there should be no transport keys in the database + assertFalse(db.containsTransportKeys(txn, contactId, transportId)); assertEquals(emptyList(), db.getTransportKeys(txn, transportId)); assertTrue(db.getTransportsWithKeys(txn).isEmpty()); @@ -710,6 +711,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { assertEquals(keySetId1, db.addTransportKeys(txn, contactId, keys1)); // Retrieve the transport keys + assertTrue(db.containsTransportKeys(txn, contactId, transportId)); Collection allKeys = db.getTransportKeys(txn, transportId); assertEquals(2, allKeys.size()); @@ -735,6 +737,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { null, updated1)); // Retrieve the transport keys again + assertTrue(db.containsTransportKeys(txn, contactId, transportId)); allKeys = db.getTransportKeys(txn, transportId); assertEquals(2, allKeys.size()); for (TransportKeySet ks : allKeys) { @@ -751,6 +754,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { // Removing the contact should remove the transport keys db.removeContact(txn, contactId); + assertFalse(db.containsTransportKeys(txn, contactId, transportId)); assertEquals(emptyList(), db.getTransportKeys(txn, transportId)); assertTrue(db.getTransportsWithKeys(txn).isEmpty());