diff --git a/apps/routerconsole/java/src/net/i2p/router/web/helpers/ConfigKeyringHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/helpers/ConfigKeyringHandler.java
index 6dde53c2019b6fa3e1fdef4607fbba17d639780a..be61a3ab615cf155e20061c68fe277fc53b52982 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/helpers/ConfigKeyringHandler.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/helpers/ConfigKeyringHandler.java
@@ -89,89 +89,82 @@ public class ConfigKeyringHandler extends FormHandler {
                         addFormError(_t("Requires hostname, destination, or blinded Base32"));
                         return;
                     }
-                    // from BlindCache
-                    List<Hash> clientBase32s = _context.netDbSegmentor().lookupClientBySigningPublicKey(spk);
-                    // TODO: This updates all of the blind data for all clients, turning the blind cache into a shared context for the owner of an encrypted leaseSet.
-                    // This is probably not ideal, with some social-engineering a service operator who owns an encrypted destination could associate 2 tunnels.
-                    // How realistic is it? Maybe not very, but I don't like it. Still, this is better than nothing.
-                    for (Hash clientBase32 : clientBase32s) {
-                        BlindData bdold = _context.clientNetDb(clientBase32).getBlindData(spk);
-                        if (bdold != null && d == null)
-                            d = bdold.getDestination();
-                        if (d != null && _context.clientManager().isLocal(d)) {
-                            // don't bother translating
-                            addFormError("Cannot add key for local destination. Enable encryption in the Hidden Services Manager.");
-                            return;
-                        }
+                    BlindData bdold = _context.netDb().getBlindData(spk);
+                    if (bdold != null && d == null)
+                        d = bdold.getDestination();
+                    if (d != null && _context.clientManager().isLocal(d)) {
+                        // don't bother translating
+                        addFormError("Cannot add key for local destination. Enable encryption in the Hidden Services Manager.");
+                        return;
+                    }
 
-                        SigType blindType;
-                        if (bdin != null) {
-                            blindType = bdin.getBlindedSigType();
-                        } else if (bdold != null) {
-                            blindType = bdold.getBlindedSigType();
-                        } else {
-                            blindType = Blinding.getDefaultBlindedType(spk.getType());
-                        }
+                    SigType blindType;
+                    if (bdin != null) {
+                        blindType = bdin.getBlindedSigType();
+                    } else if (bdold != null) {
+                        blindType = bdold.getBlindedSigType();
+                    } else {
+                        blindType = Blinding.getDefaultBlindedType(spk.getType());
+                    }
 
-                        int atype;
-                        PrivateKey pk;
-                        if (_mode == 4 || _mode == 5) {
-                            atype = BlindData.AUTH_PSK;
-                            // use supplied pk
-                            pk = new PrivateKey(EncType.ECIES_X25519, b);
-                        } else if (_mode == 6 || _mode == 7) {
-                            atype = BlindData.AUTH_DH;
-                            // create new pk
-                            b = new byte[32];
-                            _context.random().nextBytes(b);
-                            pk = new PrivateKey(EncType.ECIES_X25519, b);
-                        } else {
-                            // modes 2 and 3
-                            atype = BlindData.AUTH_NONE;
-                            pk = null;
+                    int atype;
+                    PrivateKey pk;
+                    if (_mode == 4 || _mode == 5) {
+                        atype = BlindData.AUTH_PSK;
+                        // use supplied pk
+                        pk = new PrivateKey(EncType.ECIES_X25519, b);
+                    } else if (_mode == 6 || _mode == 7) {
+                        atype = BlindData.AUTH_DH;
+                        // create new pk
+                        b = new byte[32];
+                        _context.random().nextBytes(b);
+                        pk = new PrivateKey(EncType.ECIES_X25519, b);
+                    } else {
+                        // modes 2 and 3
+                        atype = BlindData.AUTH_NONE;
+                        pk = null;
+                    }
+                    if (_mode == 2 || _mode == 4 || _mode == 6)
+                        _secret = null;
+                    if (bdin != null) {
+                        // more checks based on supplied b33
+                        if (bdin.getSecretRequired() && _secret == null) {
+                            addFormError(_t("Destination requires lookup password"));
+                            return;
                         }
-                        if (_mode == 2 || _mode == 4 || _mode == 6)
-                            _secret = null;
-                        if (bdin != null) {
-                            // more checks based on supplied b33
-                            if (bdin.getSecretRequired() && _secret == null) {
-                                addFormError(_t("Destination requires lookup password"));
-                                return;
-                            }
-                            if (!bdin.getSecretRequired() && _secret != null) {
-                                addFormError(_t("Destination does not require lookup password"));
-                                return;
-                            }
-                            if (bdin.getAuthRequired() && pk == null) {
-                                addFormError(_t("Destination requires encryption key"));
-                                return;
-                            }
-                            if (!bdin.getAuthRequired() && pk != null) {
-                                addFormError(_t("Destination does not require encryption key"));
-                                return;
-                            }
+                        if (!bdin.getSecretRequired() && _secret != null) {
+                            addFormError(_t("Destination does not require lookup password"));
+                            return;
                         }
-
-                        // to BlindCache
-                        BlindData bdout;
-                        if (d != null) {
-                            bdout = new BlindData(_context, d, blindType, _secret, atype, pk);
-                        } else {
-                            bdout = new BlindData(_context, spk, blindType, _secret, atype, pk);
+                        if (bdin.getAuthRequired() && pk == null) {
+                            addFormError(_t("Destination requires encryption key"));
+                            return;
                         }
-                        if (bdold != null) {
-                            if (_log.shouldDebug())
-                                _log.debug("already cached: " + bdold);
+                        if (!bdin.getAuthRequired() && pk != null) {
+                            addFormError(_t("Destination does not require encryption key"));
+                            return;
                         }
-                        try {
-                            _context.clientNetDb(clientBase32).setBlindData(bdout);
-                            addFormNotice(_t("Key for {0} added to keyring", bdout.toBase32()));
-                            if (_mode == 6 || _mode == 7) {
-                                addFormNotice(_t("Send key to server operator.") + ' ' + pk.toPublic().toBase64());
-                            }
-                        } catch (IllegalArgumentException iae) {
-                            addFormError(_t("Invalid destination") + ": " + iae.getLocalizedMessage());
+                    }
+
+                    // to BlindCache
+                    BlindData bdout;
+                    if (d != null) {
+                        bdout = new BlindData(_context, d, blindType, _secret, atype, pk);
+                    } else {
+                        bdout = new BlindData(_context, spk, blindType, _secret, atype, pk);
+                    }
+                    if (bdold != null) {
+                        if (_log.shouldDebug())
+                            _log.debug("already cached: " + bdold);
+                    }
+                    try {
+                        _context.netDb().setBlindData(bdout);
+                        addFormNotice(_t("Key for {0} added to keyring", bdout.toBase32()));
+                        if (_mode == 6 || _mode == 7) {
+                            addFormNotice(_t("Send key to server operator.") + ' ' + pk.toPublic().toBase64());
                         }
+                    } catch (IllegalArgumentException iae) {
+                        addFormError(_t("Invalid destination") + ": " + iae.getLocalizedMessage());
                     }
                 }
         } else if (_action.equals(_t("Delete key")) && _revokes != null) {
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/helpers/ConfigKeyringHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/helpers/ConfigKeyringHelper.java
index 63712288a8b6e17d33c0e9a3101e9685a5554dd6..3f5fc177b9c0bb2675ec0aa0b6da829dbc6c5033 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/helpers/ConfigKeyringHelper.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/helpers/ConfigKeyringHelper.java
@@ -104,7 +104,7 @@ public class ConfigKeyringHelper extends HelperBase {
         }
         // LS2
         if (!local) {
-            List<BlindData> bdata = _context.netDbSegmentor().getLocalClientsBlindData();
+            List<BlindData> bdata = _context.netDb().getBlindData();
             if (bdata.size() > 1)
                 Collections.sort(bdata, new BDComparator());
             for (BlindData bd : bdata) {
diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java b/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java
index b7da715250533175d8fa4cd777c316ad4a776278..93cc2398720df9d346ad63498f221d02976d77a3 100644
--- a/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java
+++ b/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java
@@ -180,12 +180,13 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
         _peerSelector = createPeerSelector();
         _publishingLeaseSets = new HashMap<Hash, RepublishLeaseSetJob>(8);
         _activeRequests = new HashMap<Hash, SearchJob>(8);
-        if (!isMainDb())
+        if (!isMainDb()) {
             _reseedChecker = null;
-        else
+            _blindCache = null;
+        } else {
             _reseedChecker = new ReseedChecker(context);
-        _blindCache = new BlindCache(context);
-        
+            _blindCache = new BlindCache(context);
+        }
         _localKey = null;
         if (_log.shouldLog(Log.DEBUG))
             _log.debug("Created KademliaNetworkDatabaseFacade for id: " + dbid);
@@ -223,6 +224,20 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
         return _reseedChecker;
     }
 
+    /**
+     * We still always use a single blind cache in the main Db(for now),
+     * see issue #421 on i2pgit.org/i2p-hackers/i2p.i2p for details.
+     * This checks if we're the main DB already and returns our blind
+     * cache if we are. If not, it looks up the main Db and gets it.
+     * 
+     * @return
+     */
+    protected BlindCache blindCache() {
+        if (isMainDb())
+            return _blindCache;
+        return _context.netDb().blindCache();
+    }
+
     KBucketSet<Hash> getKBuckets() { return _kb; }
     DataStore getDataStore() { return _ds; }
     
@@ -269,7 +284,8 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
         _exploreKeys.clear();
         if (_negativeCache != null)
             _negativeCache.clear();
-        _blindCache.shutdown();
+        if (isMainDb())
+            blindCache().shutdown();
     }
     
     public synchronized void restart() {
@@ -280,7 +296,8 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
         }
         _ds.restart();
         _exploreKeys.clear();
-        _blindCache.startup();
+        if (isMainDb())
+            blindCache().startup();
 
         _initialized = true;
         
@@ -370,7 +387,8 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
             throw new RuntimeException("Unable to initialize netdb storage", ioe);
         }
         _negativeCache = new NegativeLookupCache(_context);
-        _blindCache.startup();
+        if (isMainDb())
+            blindCache().startup();
         
         createHandlers();
         
@@ -558,7 +576,7 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
      */
     @Override
     public BlindData getBlindData(SigningPublicKey spk) {
-        return _blindCache.getData(spk);
+        return blindCache().getData(spk);
     }
     
     /**
@@ -569,7 +587,7 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
     public void setBlindData(BlindData bd) {
         if (_log.shouldWarn())
             _log.warn("Adding to blind cache: " + bd);
-        _blindCache.addToCache(bd);
+        blindCache().addToCache(bd);
     }
 
     /**
@@ -578,7 +596,7 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
      */
     @Override
     public List<BlindData> getBlindData() {
-        return _blindCache.getData();
+        return blindCache().getData();
     }
 
     /**
@@ -589,7 +607,7 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
      */
     @Override
     public boolean removeBlindData(SigningPublicKey spk) {
-        return _blindCache.removeBlindData(spk);
+        return blindCache().removeBlindData(spk);
     }
 
     /**
@@ -599,7 +617,7 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
      */
     @Override
     public void routingKeyChanged() {
-        _blindCache.rollover();
+        blindCache().rollover();
         if (_log.shouldInfo())
             _log.info("UTC rollover, blind cache updated");
     }
@@ -620,7 +638,7 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
             if (ls.isCurrent(Router.CLOCK_FUDGE_FACTOR)) {
                 return rv;
             } else {
-                key = _blindCache.getHash(key);
+                key = blindCache().getHash(key);
                 fail(key);
             }
         } else if (type == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
@@ -676,7 +694,7 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
         } else {
             //if (_log.shouldLog(Log.DEBUG))
             //    _log.debug("leaseSet not found locally, running search");
-            key = _blindCache.getHash(key);
+            key = blindCache().getHash(key);
             search(key, onFindJob, onFailedLookupJob, timeoutMs, true, fromLocalDest);
         }
         //if (_log.shouldLog(Log.DEBUG))
@@ -693,7 +711,7 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
      */
     public void lookupLeaseSetRemotely(Hash key, Hash fromLocalDest) {
         if (!_initialized) return;
-        key = _blindCache.getHash(key);
+        key = blindCache().getHash(key);
         if (isNegativeCached(key))
             return;
         search(key, null, null, 20*1000, true, fromLocalDest);
@@ -710,7 +728,7 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
     public void lookupLeaseSetRemotely(Hash key, Job onFindJob, Job onFailedLookupJob,
                                        long timeoutMs, Hash fromLocalDest) {
         if (!_initialized) return;
-        key = _blindCache.getHash(key);
+        key = blindCache().getHash(key);
         if (isNegativeCached(key))
             return;
         search(key, onFindJob, onFailedLookupJob, timeoutMs, true, fromLocalDest);
@@ -728,7 +746,7 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
                 if (ls.isCurrent(Router.CLOCK_FUDGE_FACTOR)) {
                     return ls;
                 } else {
-                    key = _blindCache.getHash(key);
+                    key = blindCache().getHash(key);
                     fail(key);
                     // this was an interesting key, so either refetch it or simply explore with it
                     _exploreKeys.add(key);
@@ -764,7 +782,7 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
                 _log.info("Negative cached, not searching dest: " + key);
             _context.jobQueue().addJob(onFinishedJob);
         } else {
-            key = _blindCache.getHash(key);
+            key = blindCache().getHash(key);
             search(key, onFinishedJob, onFinishedJob, timeoutMs, true, fromLocalDest);
         }
     }
@@ -1120,7 +1138,7 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
             // set dest or key before validate() calls verifySignature() which
             // will do the decryption
             encls = (EncryptedLeaseSet) leaseSet;
-            BlindData bd = _blindCache.getReverseData(leaseSet.getSigningKey());
+            BlindData bd = blindCache().getReverseData(leaseSet.getSigningKey());
             if (bd != null) {
                 if (_log.shouldWarn())
                     _log.warn("Found blind data for encls: " + bd);
@@ -1162,7 +1180,7 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
                 // recursion
                 Destination dest = decls.getDestination();
                 store(dest.getHash(), decls);
-                _blindCache.setBlinded(dest);
+                blindCache().setBlinded(dest);
             }
         } else if (type == DatabaseEntry.KEY_TYPE_LS2 || type == DatabaseEntry.KEY_TYPE_META_LS2) {
              // if it came in via garlic
@@ -1170,7 +1188,7 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
              if (ls2.isBlindedWhenPublished()) {
                  Destination dest = leaseSet.getDestination();
                  if (dest != null)
-                    _blindCache.setBlinded(dest, null, null);
+                    blindCache().setBlinded(dest, null, null);
             }
         }