From 0a802bbe0b4035accdb9d5e5bdeff275996ce7af Mon Sep 17 00:00:00 2001
From: akwizgran <michael@briarproject.org>
Date: Tue, 27 Mar 2018 17:30:25 +0100
Subject: [PATCH] Add a method for removing unbound transport keys.

---
 .../bramble/api/db/DatabaseComponent.java     |  6 +++
 .../bramble/api/transport/KeyManager.java     |  7 +++
 .../org/briarproject/bramble/db/Database.java |  6 +++
 .../bramble/db/DatabaseComponentImpl.java     | 10 ++++
 .../briarproject/bramble/db/JdbcDatabase.java | 47 ++++++++++---------
 .../bramble/transport/KeyManagerImpl.java     | 14 ++++++
 .../transport/TransportKeyManager.java        |  2 +
 .../transport/TransportKeyManagerImpl.java    | 14 ++++++
 8 files changed, 83 insertions(+), 23 deletions(-)

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 2a4f262de8..fcf5efe46c 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
@@ -481,6 +481,12 @@ public interface DatabaseComponent {
 	 */
 	void removeTransport(Transaction txn, TransportId t) throws DbException;
 
+	/**
+	 * Removes the given transport keys from the database.
+	 */
+	void removeTransportKeys(Transaction txn, TransportId t, KeySetId k)
+		throws DbException;
+
 	/**
 	 * Marks the given contact as verified.
 	 */
diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/transport/KeyManager.java b/bramble-api/src/main/java/org/briarproject/bramble/api/transport/KeyManager.java
index 50a5cf9480..06b2f47258 100644
--- a/bramble-api/src/main/java/org/briarproject/bramble/api/transport/KeyManager.java
+++ b/bramble-api/src/main/java/org/briarproject/bramble/api/transport/KeyManager.java
@@ -40,6 +40,13 @@ public interface KeyManager {
 	void bindKeys(Transaction txn, ContactId c, Map<TransportId, KeySetId> keys)
 			throws DbException;
 
+	/**
+	 * Removes the given transport keys, which must not have been bound, from
+	 * the manager and the database.
+	 */
+	void removeKeys(Transaction txn, Map<TransportId, KeySetId> keys)
+		throws DbException;
+
 	/**
 	 * Returns a {@link StreamContext} for sending a stream to the given
 	 * contact over the given transport, or null if an error occurs or the
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 b11e1b8281..6ee996b2b8 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
@@ -593,6 +593,12 @@ interface Database<T> {
 	 */
 	void removeTransport(T txn, TransportId t) throws DbException;
 
+	/**
+	 * Removes the given transport keys from the database.
+	 */
+	void removeTransportKeys(T txn, TransportId t, KeySetId k)
+			throws DbException;
+
 	/**
 	 * Resets the transmission count and expiry time of the given message with
 	 * respect 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 305b672900..697bcdd3d6 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
@@ -791,6 +791,16 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
 		db.removeTransport(txn, t);
 	}
 
+	@Override
+	public void removeTransportKeys(Transaction transaction,
+			TransportId t, KeySetId k) throws DbException {
+		if (transaction.isReadOnly()) throw new IllegalArgumentException();
+		T txn = unbox(transaction);
+		if (!db.containsTransport(txn, t))
+			throw new NoSuchTransportException();
+		db.removeTransportKeys(txn, t, k);
+	}
+
 	@Override
 	public void setContactVerified(Transaction transaction, ContactId c)
 			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 747145a344..25cfb4d5aa 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
@@ -2681,6 +2681,27 @@ abstract class JdbcDatabase implements Database<Connection> {
 		}
 	}
 
+	@Override
+	public void removeTransportKeys(Connection txn, TransportId t, KeySetId k)
+			throws DbException {
+		PreparedStatement ps = null;
+		try {
+			// Delete any existing outgoing keys - this will also remove any
+			// incoming keys with the same key set ID
+			String sql = "DELETE FROM outgoingKeys"
+					+ " WHERE transportId = ? AND keySetId = ?";
+			ps = txn.prepareStatement(sql);
+			ps.setString(1, t.getString());
+			ps.setInt(2, k.getInt());
+			int affected = ps.executeUpdate();
+			if (affected < 0) throw new DbStateException();
+			ps.close();
+		} catch (SQLException e) {
+			tryToClose(ps);
+			throw new DbException(e);
+		}
+	}
+
 	@Override
 	public void resetExpiryTime(Connection txn, ContactId c, MessageId m)
 			throws DbException {
@@ -2905,30 +2926,10 @@ abstract class JdbcDatabase implements Database<Connection> {
 	@Override
 	public void updateTransportKeys(Connection txn, Collection<KeySet> keys)
 			throws DbException {
-		PreparedStatement ps = null;
-		try {
-			// Delete any existing outgoing keys - this will also remove any
-			// incoming keys with the same key set ID
-			// TODO: Add an index to speed this up?
-			String sql = "DELETE FROM outgoingKeys WHERE keySetId = ?";
-			ps = txn.prepareStatement(sql);
-			for (KeySet ks : keys) {
-				ps.setInt(1, ks.getKeySetId().getInt());
-				ps.addBatch();
-			}
-			int[] batchAffected = ps.executeBatch();
-			if (batchAffected.length != keys.size())
-				throw new DbStateException();
-			for (int rows: batchAffected)
-				if (rows < 0) throw new DbStateException();
-			ps.close();
-		} catch (SQLException e) {
-			tryToClose(ps);
-			throw new DbException(e);
-		}
-		// Store the new keys
 		for (KeySet ks : keys) {
-			addTransportKeys(txn, ks.getContactId(), ks.getTransportKeys());
+			TransportKeys k = ks.getTransportKeys();
+			removeTransportKeys(txn, k.getTransportId(), ks.getKeySetId());
+			addTransportKeys(txn, ks.getContactId(), k);
 		}
 	}
 }
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/transport/KeyManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/transport/KeyManagerImpl.java
index c07c9e1e72..1a06ef4a65 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/transport/KeyManagerImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/transport/KeyManagerImpl.java
@@ -132,6 +132,20 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
 		}
 	}
 
+	@Override
+	public void removeKeys(Transaction txn, Map<TransportId, KeySetId> keys)
+			throws DbException {
+		for (Entry<TransportId, KeySetId> e : keys.entrySet()) {
+			TransportId t = e.getKey();
+			TransportKeyManager m = managers.get(t);
+			if (m == null) {
+				if (LOG.isLoggable(INFO)) LOG.info("No key manager for " + t);
+			} else {
+				m.removeKeys(txn, e.getValue());
+			}
+		}
+	}
+
 	@Override
 	public StreamContext getStreamContext(ContactId c, TransportId t)
 			throws DbException {
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/transport/TransportKeyManager.java b/bramble-core/src/main/java/org/briarproject/bramble/transport/TransportKeyManager.java
index 41e31fbe62..4eff0b289d 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/transport/TransportKeyManager.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/transport/TransportKeyManager.java
@@ -23,6 +23,8 @@ interface TransportKeyManager {
 
 	void bindKeys(Transaction txn, ContactId c, KeySetId k) throws DbException;
 
+	void removeKeys(Transaction txn, KeySetId k) throws DbException;
+
 	void removeContact(ContactId c);
 
 	@Nullable
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/transport/TransportKeyManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/transport/TransportKeyManagerImpl.java
index 6b9a1519eb..889485d0dc 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/transport/TransportKeyManagerImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/transport/TransportKeyManagerImpl.java
@@ -219,6 +219,20 @@ class TransportKeyManagerImpl implements TransportKeyManager {
 		}
 	}
 
+	@Override
+	public void removeKeys(Transaction txn, KeySetId k) throws DbException {
+		lock.lock();
+		try {
+			MutableKeySet ks = keys.remove(k);
+			if (ks == null) throw new IllegalArgumentException();
+			if (ks.getContactId() != null) throw new IllegalArgumentException();
+			TransportId t = ks.getTransportKeys().getTransportId();
+			db.removeTransportKeys(txn, t, k);
+		} finally {
+			lock.unlock();
+		}
+	}
+
 	@Override
 	public void removeContact(ContactId c) {
 		lock.lock();
-- 
GitLab