diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillStoreJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillStoreJob.java
index b7ad0465fa721fe927dc18359ecdceaf5cb1a46c..854432a6a06aeabbcbf689af572d2d5cb3debd45 100644
--- a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillStoreJob.java
+++ b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillStoreJob.java
@@ -79,6 +79,7 @@ class FloodfillStoreJob extends StoreJob {
             }
 
             long published = data.getDate();
+            boolean isls2 = data.isLeaseSet() && data.getType() != DatabaseEntry.KEY_TYPE_LEASESET;
 
             // we should always have exactly one successful entry
             Hash sentTo = null;
@@ -86,7 +87,8 @@ class FloodfillStoreJob extends StoreJob {
                 sentTo = _state.getSuccessful().iterator().next();
             } catch (NoSuchElementException nsee) {}
             getContext().jobQueue().addJob(new FloodfillVerifyStoreJob(getContext(), _state.getTarget(),
-                                                                       published, isRouterInfo, sentTo, _facade));
+                                                                       published, isRouterInfo, isls2,
+                                                                       sentTo, _facade));
     }
     
     @Override
diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillVerifyStoreJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillVerifyStoreJob.java
index a2b8b4d5c03097682a9a41188b8e0fbb55d2b6a1..5e09087cd9cd72af2eaee6303c86f076622c7140 100644
--- a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillVerifyStoreJob.java
+++ b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillVerifyStoreJob.java
@@ -38,6 +38,7 @@ class FloodfillVerifyStoreJob extends JobImpl {
     private long _sendTime;
     private final long _published;
     private final boolean _isRouterInfo;
+    private final boolean _isLS2;
     private MessageWrapper.WrappedMessage _wrappedMessage;
     private final Set<Hash> _ignore;
     private final MaskedIPSet _ipSet;
@@ -52,12 +53,14 @@ class FloodfillVerifyStoreJob extends JobImpl {
      *  Delay a few seconds, then start the verify
      *  @param sentTo who to give the credit or blame to, can be null
      */
-    public FloodfillVerifyStoreJob(RouterContext ctx, Hash key, long published, boolean isRouterInfo, Hash sentTo, FloodfillNetworkDatabaseFacade facade) {
+    public FloodfillVerifyStoreJob(RouterContext ctx, Hash key, long published, boolean isRouterInfo,
+                                   boolean isLS2, Hash sentTo, FloodfillNetworkDatabaseFacade facade) {
         super(ctx);
         facade.verifyStarted(key);
         _key = key;
         _published = published;
         _isRouterInfo = isRouterInfo;
+        _isLS2 = isLS2;
         _log = ctx.logManager().getLog(getClass());
         _sentTo = sentTo;
         _facade = facade;
@@ -195,7 +198,8 @@ class FloodfillVerifyStoreJob extends JobImpl {
                 Hash peer = peers.get(0);
                 RouterInfo ri = _facade.lookupRouterInfoLocally(peer);
                 //if (ri != null && StoreJob.supportsCert(ri, keyCert)) {
-                if (ri != null && StoreJob.shouldStoreTo(ri)) {
+                if (ri != null && StoreJob.shouldStoreTo(ri) &&
+                    (!_isLS2 || StoreJob.shouldStoreLS2To(ri))) {
                     Set<String> peerIPs = new MaskedIPSet(getContext(), ri, IP_CLOSE_BYTES);
                     if (!_ipSet.containsAny(peerIPs)) {
                         _ipSet.addAll(peerIPs);
diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/StoreJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/StoreJob.java
index f901a3b54686116f927a9bfe89f838694c3d0015..5adc238f54d3ebf86fe9e5418d5cb54d0c56f7be 100644
--- a/router/java/src/net/i2p/router/networkdb/kademlia/StoreJob.java
+++ b/router/java/src/net/i2p/router/networkdb/kademlia/StoreJob.java
@@ -180,6 +180,8 @@ abstract class StoreJob extends JobImpl {
             //_state.addPending(closestHashes);
             int queued = 0;
             int skipped = 0;
+            int type = _state.getData().getType();
+            boolean isls2 = DatabaseEntry.isLeaseSet(type) && type != DatabaseEntry.KEY_TYPE_LEASESET;
             for (Hash peer : closestHashes) {
                 DatabaseEntry ds = _facade.getDataStore().get(peer);
                 if ( (ds == null) || !(ds.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO) ) {
@@ -192,24 +194,12 @@ abstract class StoreJob extends JobImpl {
                         _log.info(getJobId() + ": Skipping old router " + peer);
                     _state.addSkipped(peer);
                     skipped++;
-/****
-   above shouldStoreTo() check is newer than these two checks, so we're covered
-
-                } else if (_state.getData().getType() == DatabaseEntry.KEY_TYPE_LEASESET &&
-                           !supportsCert((RouterInfo)ds,
-                                         ((LeaseSet)_state.getData()).getDestination().getCertificate())) {
-                    if (_log.shouldLog(Log.INFO))
-                        _log.info(getJobId() + ": Skipping router that doesn't support key certs " + peer);
-                    _state.addSkipped(peer);
-                    skipped++;
-                } else if (_state.getData().getType() == DatabaseEntry.KEY_TYPE_LEASESET &&
-                           ((LeaseSet)_state.getData()).getLeaseCount() > 6 &&
-                           !supportsBigLeaseSets((RouterInfo)ds)) {
+                } else if (isls2 &&
+                           !shouldStoreLS2To((RouterInfo)ds)) {
                     if (_log.shouldLog(Log.INFO))
-                        _log.info(getJobId() + ": Skipping router that doesn't support big leasesets " + peer);
+                        _log.info(getJobId() + ": Skipping router that doesn't support LS2 " + peer);
                     _state.addSkipped(peer);
                     skipped++;
-****/
                 } else {
                     int peerTimeout = _facade.getPeerTimeout(peer);
 
@@ -469,8 +459,7 @@ abstract class StoreJob extends JobImpl {
         TunnelInfo outTunnel = getContext().tunnelManager().selectOutboundTunnel(client, to);
         if (outTunnel != null) {
             I2NPMessage sent;
-            boolean shouldEncrypt = supportsEncryption(peer);
-            if (shouldEncrypt) {
+
                 // garlic encrypt
                 MessageWrapper.WrappedMessage wm = MessageWrapper.wrap(getContext(), msg, client, peer);
                 if (wm == null) {
@@ -481,14 +470,6 @@ abstract class StoreJob extends JobImpl {
                 }
                 sent = wm.getMessage();
                 _state.addPending(to, wm);
-            } else {
-                _state.addPending(to);
-                // now that almost all floodfills are at 0.7.10,
-                // just refuse to store unencrypted to older ones.
-                _state.replyTimeout(to);
-                getContext().jobQueue().addJob(new WaitJob(getContext()));
-                return;
-            }
 
             SendSuccessJob onReply = new SendSuccessJob(getContext(), peer, outTunnel, sent.getMessageSize());
             FailedJob onFail = new FailedJob(getContext(), peer, getContext().clock().now());
@@ -527,65 +508,28 @@ abstract class StoreJob extends JobImpl {
         public String getName() { return "Kademlia Store Send Delay"; }
     }
 
-    private static final String MIN_ENCRYPTION_VERSION = "0.7.10";
-
-    /**
-     * *sigh*
-     * sadly due to a bug in HandleFloodfillDatabaseStoreMessageJob, where
-     * a floodfill would not flood anything that arrived garlic-wrapped
-     * @since 0.7.10
-     */
-    private static boolean supportsEncryption(RouterInfo ri) {
-        String v = ri.getVersion();
-        return VersionComparator.comp(v, MIN_ENCRYPTION_VERSION) >= 0;
-    }
-
-    /**
-     * Does this router understand this cert?
-     * @return true if not a key cert
-     * @since 0.9.12
-     */
-/****
-    public static boolean supportsCert(RouterInfo ri, Certificate cert) {
-        if (cert.getCertificateType() != Certificate.CERTIFICATE_TYPE_KEY)
-            return true;
-        SigType type;
-        try {
-            type = cert.toKeyCertificate().getSigType();
-        } catch (DataFormatException dfe) {
-            return false;
-        }
-        if (type == null)
-            return false;
-        String v = ri.getVersion();
-        String since = type.getSupportedSince();
-        return VersionComparator.comp(v, since) >= 0;
-    }
-
-    private static final String MIN_BIGLEASESET_VERSION = "0.9";
-****/
+    /** @since 0.9.28 */
+    public static final String MIN_STORE_VERSION = "0.9.28";
 
     /**
-     * Does he support more than 6 leasesets?
-     * @since 0.9.12
+     * Is it too old?
+     * @since 0.9.33
      */
-/****
-    private static boolean supportsBigLeaseSets(RouterInfo ri) {
+    static boolean shouldStoreTo(RouterInfo ri) {
         String v = ri.getVersion();
-        return VersionComparator.comp(v, MIN_BIGLEASESET_VERSION) >= 0;
+        return VersionComparator.comp(v, MIN_STORE_VERSION) >= 0;
     }
-****/
 
-    /** */
-    public static final String MIN_STORE_VERSION = "0.9.28";
+    /** @since 0.9.38 */
+    public static final String MIN_STORE_LS2_VERSION = "0.9.38";
 
     /**
      * Is it too old?
-     * @since 0.9.33
+     * @since 0.9.38
      */
-    static boolean shouldStoreTo(RouterInfo ri) {
+    static boolean shouldStoreLS2To(RouterInfo ri) {
         String v = ri.getVersion();
-        return VersionComparator.comp(v, MIN_STORE_VERSION) >= 0;
+        return VersionComparator.comp(v, MIN_STORE_LS2_VERSION) >= 0;
     }
 
     /**