net.i2p.router.networkdb.kademlia

## Class KademliaNetworkDatabaseFacade

- java.lang.Object
- - net.i2p.router.NetworkDatabaseFacade
  - - net.i2p.router.networkdb.kademlia.KademliaNetworkDatabaseFacade

- All Implemented Interfaces:
    Service
  Direct Known Subclasses:
    FloodfillNetworkDatabaseFacade

      public abstract class KademliaNetworkDatabaseFacade
      extends NetworkDatabaseFacade

  Kademlia based version of network database.

  Provides core network database functionality using Kademlia DHT for peer discovery, routing table management, and data storage/lookup operations. Never instantiated directly; see FloodfillNetworkDatabaseFacade.

- - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `protected RouterContext` | `_context`
    `protected Log` | `_log`
    `protected int` | `_networkID`
    `protected PeerSelector` | `_peerSelector`
    `static String` | `CURRENT_VERSION`
    `static String` | `DEFAULT_DB_DIR`
    `static long` | `DONT_FAIL_PERIOD` For 15 minutes after startup, don't fail db entries so that if we were offline for a while, we'll have a chance of finding some live peers with the previous references
    `(package private) static int` | `MAX_EXPLORE_QUEUE` Maximum number of peers to place in the queue to explore
    `protected static int` | `MIN_REMAINING_ROUTERS` If we have less than this many routers left, don't drop any more, even if they're failing or doing bad stuff.
    `(package private) static int` | `MIN_RESEED` Reseed if below this.
    `static String` | `MIN_VERSION`
    `static String` | `minRouterVersion`
    `static String` | `PROP_BLOCK_MY_COUNTRY`
    `static String` | `PROP_BLOCK_XG`
    `(package private) static String` | `PROP_BUCKET_SIZE`
    `static String` | `PROP_DB_DIR`
    `(package private) static String` | `PROP_EXPLORE_QUEUE`
    `static String` | `PROP_IP_COUNTRY`
    `(package private) static String` | `PROP_KAD_B`
    `(package private) static String` | `PROP_MIN_ROUTER_VERSION`
    `(package private) static String` | `PROP_ROUTER_INFO_EXPIRATION_ADJUSTED`
    `(package private) static String` | `PROP_VALIDATE_ROUTERS_AFTER`
    `protected static long` | `PUBLISH_JOB_DELAY` This needs to be long enough to give us time to start up, but less than 20m (when we start accepting tunnels and could be a IBGW) Actually no, we need this soon if we are a new router or other routers have forgotten about us, else we can't build IB exploratory tunnels.

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `KademliaNetworkDatabaseFacade(RouterContext context, Hash dbid)` Initializes the Kademlia-based network database facade.

  - ### Method Summary

    All Methods Static Methods Instance Methods Abstract Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `protected BlindCache` | `blindCache()` Returns the blind data cache used by this database.
    `protected void` | `createHandlers()` unused, see override
    `protected PeerSelector` | `createPeerSelector()` Creates a peer selector for the network database.
    `(package private) boolean` | `dropAfterLookupFailed(Hash peer)` Final remove for a router info.
    `void` | `fail(Hash dbEntry)` Final remove for a leaseset.
    `(package private) void` | `failPermanently(Destination dest)` Negative cache until restart
    `Set<Hash>` | `findNearestRouters(Hash key, int maxNumRouters, Set<Hash> peersToIgnore)` Get the routers closest to that key in response to a remote lookup Only used by ../HDLMJ Set MAY INCLUDE our own router - add to peersToIgnore if you don't want
    `Set<Hash>` | `getAllRouters()` get the hashes for all known routers
    `List<BlindData>` | `getBlindData()` For console ConfigKeyringHelper
    `BlindData` | `getBlindData(SigningPublicKey spk)`
    `Set<LeaseSet>` | `getClientLeases()` public for NetDbRenderer in routerconsole
    `(package private) DataStore` | `getDataStore()`
    `(package private) String` | `getDbDir()` For the main DB only.
    `Set<Hash>` | `getExploreKeys()`
    `Set<LeaseSet>` | `getFloodfillLeases()` Public for NetDbRenderer in routerconsole
    `(package private) KBucketSet<Hash>` | `getKBuckets()`
    `protected int` | `getKBucketSetSize()` The KBucketSet contains RIs only.
    `int` | `getKnownLeaseSets()` This is only used by StatisticsManager to publish the count if we are floodfill.
    `int` | `getKnownRouters()` This used to return the number of routers that were in both the kbuckets AND the data store, which was fine when the kbuckets held everything.
    `(package private) long` | `getLastExploreNewDate()`
    `long` | `getLastRouterInfoPublishTime()` The last time we successfully published our RI.
    `Set<LeaseSet>` | `getLeases()` public for NetDbRenderer in routerconsole
    `PeerSelector` | `getPeerSelector()` Returns the main database's peer selector.
    `int` | `getPeerTimeout(Hash peer)`
    `Set<LeaseSet>` | `getPublishedLeases()` public for NetDbRenderer in routerconsole
    `Set<RouterInfo>` | `getRouters()` Public for NetDbRenderer in routerconsole
    `int` | `getStoredRouterInfoCount()` Get the number of RouterInfo files stored on disk, if using PersistentDataStore.
    `Set<LeaseSet>` | `getUnpublishedLeases()` public for NetDbRenderer in routerconsole
    `(package private) boolean` | `hasActiveRepublishJob(Hash hash)` Check if an active republish job exists for the given destination.
    `boolean` | `isClientDb()` Check if the database is a client DB.
    `boolean` | `isInitialized()` Checks whether the network database has been fully initialized.
    `(package private) boolean` | `isNegativeCached(Hash key)` Is the key in the negative lookup cache?
    `boolean` | `isNegativeCachedForever(Hash key)` Is it permanently negative cached?
    `static boolean` | `isNewer(LeaseSet a, LeaseSet b)` Utility to determine if a is newer than b.
    `protected void` | `lookupBeforeDropping(Hash peer, RouterInfo info)` Don't use directly - see F.N.D.F.
    `void` | `lookupDestination(Hash key, Job onFinishedJob, long timeoutMs, Hash fromLocalDest)` Lookup using the client's tunnels Succeeds even if LS validation and store fails due to unsupported sig type, expired, etc.
    `Destination` | `lookupDestinationLocally(Hash key)` Lookup locally in netDB and in badDest cache Succeeds even if LS validation fails due to unsupported sig type, expired, etc.
    `(package private) void` | `lookupFailed(Hash key)` Increment in the negative lookup cache
    `void` | `lookupLeaseSet(Hash key, Job onFindJob, Job onFailedLookupJob, long timeoutMs)` Lookup using exploratory tunnels.
    `void` | `lookupLeaseSet(Hash key, Job onFindJob, Job onFailedLookupJob, long timeoutMs, Hash fromLocalDest)` Lookup using the client's tunnels Use lookupDestination() if you don't need the LS or don't need it validated.
    `LeaseSet` | `lookupLeaseSetLocally(Hash key)` Use lookupDestination() if you don't need the LS or don't need it validated.
    `void` | `lookupLeaseSetRemotely(Hash key, Hash fromLocalDest)` Unconditionally lookup using the client's tunnels.
    `void` | `lookupLeaseSetRemotely(Hash key, Job onFindJob, Job onFailedLookupJob, long timeoutMs, Hash fromLocalDest)` Unconditionally lookup using the client's tunnels.
    `DatabaseEntry` | `lookupLocally(Hash key)`
    `DatabaseEntry` | `lookupLocallyWithoutValidation(Hash key)` Not for use without validation
    `void` | `lookupRouterInfo(Hash key, Job onFindJob, Job onFailedLookupJob, long timeoutMs)`
    `RouterInfo` | `lookupRouterInfoLocally(Hash key)` This will return immediately with the result or null.
    `void` | `publish(LeaseSet localLeaseSet)` Publishes a local LeaseSet by storing it and scheduling republishing if applicable.
    `void` | `publish(RouterInfo localRouterInfo)` Stores to local db only.
    `void` | `queueForExploration(Collection<Hash> keys)`
    `(package private) boolean` | `registerPublishingJob(RepublishLeaseSetJob job)` Register a new job for tracking.
    `boolean` | `removeBlindData(SigningPublicKey spk)` For console ConfigKeyringHelper
    `void` | `removeFromExploreKeys(Collection<Hash> toRemove)`
    `(package private) void` | `removePublishingJob(Hash hash, RepublishLeaseSetJob job)` Remove a specific job from the tracking set.
    `void` | `renderStatusHTML(Writer out)` Debug info, HTML formatted
    `void` | `rescan()`
    `ReseedChecker` | `reseedChecker()` Returns the reseed checker for this database.
    `(package private) void` | `routerInfoPublishSuccessful()` Set the last time we successfully published our RI.
    `void` | `routingKeyChanged()` Notify the netDB that the routing key changed at midnight UTC
    `(package private) SearchJob` | `search(Hash key, Job onFindJob, Job onFailedLookupJob, long timeoutMs, boolean isLease)` Begin a kademlia style search for the key specified, which can take up to timeoutMs and will fire the appropriate jobs on success or timeout (or if the kademlia search completes without any match) Unused - called only by FNDF.searchFull() from FloodSearchJob which is overridden - don't use this.
    `(package private) SearchJob` | `search(Hash key, Job onFindJob, Job onFailedLookupJob, long timeoutMs, boolean isLease, Hash fromLocalDest)` Unused - see FNDF
    `(package private) void` | `searchComplete(Hash key)` The search for the given key is no longer active
    `(package private) abstract void` | `sendStore(Hash key, DatabaseEntry ds, Job onSuccess, Job onFailure, long sendTimeout, Set<Hash> toIgnore)` See implementation in FNDF
    `void` | `setBlindData(BlindData bd)`
    `(package private) void` | `setLastExploreNewDate(long when)`
    `void` | `shutdown()` Cannot be restarted.
    `void` | `startup()` Instruct the service that it should start normal operation.
    `(package private) void` | `stopPublishing(Hash target)`
    `LeaseSet` | `store(Hash key, LeaseSet leaseSet)`
    `LeaseSet` | `store(Hash key, LeaseSet leaseSet, boolean force)` Store the leaseSet.
    `RouterInfo` | `store(Hash key, RouterInfo routerInfo)` Store the routerInfo.
    `(package private) RouterInfo` | `store(Hash key, RouterInfo routerInfo, boolean persist)` Store the routerInfo.
    `String` | `toString()`
    `void` | `unpublish(LeaseSet localLeaseSet)`
    `String` | `validate(Hash key, LeaseSet leaseSet)` Validates whether the given LeaseSet is acceptable as valid and current based on current known parameters.
    `(package private) String` | `validate(RouterInfo routerInfo)` Determine whether this routerInfo will be accepted as valid and current given what we know now.

    - ### Methods inherited from class net.i2p.router.NetworkDatabaseFacade

      `floodfillEnabled, store`

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

    - ### Methods inherited from interface net.i2p.router.Service

      `restart`

- - ### Field Detail

    - #### _context

          protected final RouterContext _context

    - #### _log

          protected final Log _log

    - #### _networkID

          protected final int _networkID

    - #### _peerSelector

          protected final PeerSelector _peerSelector

    - #### CURRENT_VERSION

          public static String CURRENT_VERSION

    - #### DEFAULT_DB_DIR

          public static final String DEFAULT_DB_DIR

      See Also:
        Constant Field Values

    - #### DONT_FAIL_PERIOD

          public static long DONT_FAIL_PERIOD

      For 15 minutes after startup, don't fail db entries so that if we were offline for a while, we'll have a chance of finding some live peers with the previous references

    - #### MAX_EXPLORE_QUEUE

          static final int MAX_EXPLORE_QUEUE

      Maximum number of peers to place in the queue to explore
      See Also:
        Constant Field Values

    - #### MIN_REMAINING_ROUTERS

          protected static final int MIN_REMAINING_ROUTERS

      If we have less than this many routers left, don't drop any more, even if they're failing or doing bad stuff. As of 0.9.4, we make this LOWER than the min for reseeding, so a reseed will be forced if necessary.
      See Also:
        Constant Field Values

    - #### MIN_RESEED

          static final int MIN_RESEED

      Reseed if below this.
      See Also:
        Constant Field Values

    - #### MIN_VERSION

          public static final String MIN_VERSION

      See Also:
        Constant Field Values

    - #### minRouterVersion

          public static final String minRouterVersion

      See Also:
        Constant Field Values

    - #### PROP_BLOCK_MY_COUNTRY

          public static final String PROP_BLOCK_MY_COUNTRY

      See Also:
        Constant Field Values

    - #### PROP_BLOCK_XG

          public static final String PROP_BLOCK_XG

      See Also:
        Constant Field Values

    - #### PROP_BUCKET_SIZE

          static final String PROP_BUCKET_SIZE

      See Also:
        Constant Field Values

    - #### PROP_DB_DIR

          public static final String PROP_DB_DIR

      See Also:
        Constant Field Values

    - #### PROP_EXPLORE_QUEUE

          static final String PROP_EXPLORE_QUEUE

      See Also:
        Constant Field Values

    - #### PROP_IP_COUNTRY

          public static final String PROP_IP_COUNTRY

      See Also:
        Constant Field Values

    - #### PROP_KAD_B

          static final String PROP_KAD_B

      See Also:
        Constant Field Values

    - #### PROP_MIN_ROUTER_VERSION

          static final String PROP_MIN_ROUTER_VERSION

      See Also:
        Constant Field Values

    - #### PROP_ROUTER_INFO_EXPIRATION_ADJUSTED

          static final String PROP_ROUTER_INFO_EXPIRATION_ADJUSTED

      See Also:
        Constant Field Values

    - #### PROP_VALIDATE_ROUTERS_AFTER

          static final String PROP_VALIDATE_ROUTERS_AFTER

      See Also:
        Constant Field Values

    - #### PUBLISH_JOB_DELAY

          protected static final long PUBLISH_JOB_DELAY

      This needs to be long enough to give us time to start up, but less than 20m (when we start accepting tunnels and could be a IBGW) Actually no, we need this soon if we are a new router or other routers have forgotten about us, else we can't build IB exploratory tunnels. Unused.
      See Also:
        Constant Field Values

  - ### Constructor Detail

    - #### KademliaNetworkDatabaseFacade

          public KademliaNetworkDatabaseFacade(RouterContext context,
                                               Hash dbid)

      Initializes the Kademlia-based network database facade.
      Parameters:
        `context` - the router context
        `dbid` - the unique identifier for this network database

  - ### Method Detail

    - #### blindCache

          protected BlindCache blindCache()

      Returns the blind data cache used by this database. 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.
      Returns:
        the BlindCache instance, never null

    - #### createHandlers

          protected void createHandlers()

      unused, see override

    - #### createPeerSelector

          protected PeerSelector createPeerSelector()

      Creates a peer selector for the network database. Only applicable for the main database.
      Returns:
        a new PeerSelector instance
      Throws:
        `IllegalStateException` - if called on a client database

    - #### dropAfterLookupFailed

          boolean dropAfterLookupFailed(Hash peer)

      Final remove for a router info. Do NOT use for leasesets.

    - #### fail

          public void fail(Hash dbEntry)

      Final remove for a leaseset. For a router info, will look up in the network before dropping.
      Specified by:
        `fail` in class `NetworkDatabaseFacade`

    - #### failPermanently

          void failPermanently(Destination dest)

      Negative cache until restart

    - #### findNearestRouters

          public Set<Hash> findNearestRouters(Hash key,
                                              int maxNumRouters,
                                              Set<Hash> peersToIgnore)

      Get the routers closest to that key in response to a remote lookup Only used by ../HDLMJ Set MAY INCLUDE our own router - add to peersToIgnore if you don't want
      Specified by:
        `findNearestRouters` in class `NetworkDatabaseFacade`
      Parameters:
        `key` - the real key, NOT the routing key
        `peersToIgnore` - can be null
        `maxNumRouters` - The maximum number of routers to return

    - #### getAllRouters

          public Set<Hash> getAllRouters()

      get the hashes for all known routers
      Specified by:
        `getAllRouters` in class `NetworkDatabaseFacade`

    - #### getBlindData

          public List<BlindData> getBlindData()

      For console ConfigKeyringHelper
      Overrides:
        `getBlindData` in class `NetworkDatabaseFacade`

    - #### getBlindData

          public BlindData getBlindData(SigningPublicKey spk)

      Overrides:
        `getBlindData` in class `NetworkDatabaseFacade`
      Parameters:
        `spk` - unblinded key
      Returns:
        BlindData or null

    - #### getClientLeases

          public Set<LeaseSet> getClientLeases()

      public for NetDbRenderer in routerconsole
      Overrides:
        `getClientLeases` in class `NetworkDatabaseFacade`

    - #### getDataStore

          DataStore getDataStore()

    - #### getDbDir

          String getDbDir()

      For the main DB only. Sub DBs are not persisted and must not access this directory.
      Returns:
        null before startup() is called; non-null thereafter, even for subdbs.

    - #### getExploreKeys

          public Set<Hash> getExploreKeys()

      Returns:
        unmodifiable set

    - #### getFloodfillLeases

          public Set<LeaseSet> getFloodfillLeases()

      Public for NetDbRenderer in routerconsole
      Overrides:
        `getFloodfillLeases` in class `NetworkDatabaseFacade`

    - #### getKBuckets

          KBucketSet<Hash> getKBuckets()

      Returns:
        the main DB's KBucketSet. Client DBs do not have their own.

    - #### getKBucketSetSize

          protected int getKBucketSetSize()

      The KBucketSet contains RIs only.

    - #### getKnownLeaseSets

          public int getKnownLeaseSets()

      This is only used by StatisticsManager to publish the count if we are floodfill. So to hide a clue that a popular eepsite is hosted on a floodfill router, only count leasesets that are "received as published", as of 0.7.14
      Overrides:
        `getKnownLeaseSets` in class `NetworkDatabaseFacade`

    - #### getKnownRouters

          public int getKnownRouters()

      This used to return the number of routers that were in both the kbuckets AND the data store, which was fine when the kbuckets held everything. But now that is probably not what you want. Just return the count in the data store.
      Overrides:
        `getKnownRouters` in class `NetworkDatabaseFacade`
      Returns:
        0 if this is a client DB

    - #### getLastExploreNewDate

          long getLastExploreNewDate()

    - #### getLastRouterInfoPublishTime

          public long getLastRouterInfoPublishTime()

      The last time we successfully published our RI.
      Overrides:
        `getLastRouterInfoPublishTime` in class `NetworkDatabaseFacade`

    - #### getLeases

          public Set<LeaseSet> getLeases()

      public for NetDbRenderer in routerconsole
      Overrides:
        `getLeases` in class `NetworkDatabaseFacade`

    - #### getPeerSelector

          public PeerSelector getPeerSelector()

      Returns the main database's peer selector.
      Returns:
        the PeerSelector instance, or null if this is a client database

    - #### getPeerTimeout

          public int getPeerTimeout(Hash peer)

      Returns:
        the timeout for a peer, based on the profile data, or the default timeout

    - #### getPublishedLeases

          public Set<LeaseSet> getPublishedLeases()

      public for NetDbRenderer in routerconsole
      Overrides:
        `getPublishedLeases` in class `NetworkDatabaseFacade`

    - #### getRouters

          public Set<RouterInfo> getRouters()

      Public for NetDbRenderer in routerconsole
      Overrides:
        `getRouters` in class `NetworkDatabaseFacade`
      Returns:
        empty set if this is a client DB

    - #### getStoredRouterInfoCount

          public int getStoredRouterInfoCount()

      Get the number of RouterInfo files stored on disk, if using PersistentDataStore.
      Returns:
        number of RIs on disk, or 0 if not using persistent storage

    - #### getUnpublishedLeases

          public Set<LeaseSet> getUnpublishedLeases()

      public for NetDbRenderer in routerconsole
      Overrides:
        `getUnpublishedLeases` in class `NetworkDatabaseFacade`

    - #### hasActiveRepublishJob

          boolean hasActiveRepublishJob(Hash hash)

      Check if an active republish job exists for the given destination.

    - #### isClientDb

          public boolean isClientDb()

      Check if the database is a client DB.
      Returns:
        true if the database is a client DB, false otherwise

    - #### isInitialized

          public boolean isInitialized()

      Checks whether the network database has been fully initialized.
      Overrides:
        `isInitialized` in class `NetworkDatabaseFacade`
      Returns:
        true if the database is initialized and ready for use, false otherwise

    - #### isNegativeCached

          boolean isNegativeCached(Hash key)

      Is the key in the negative lookup cache?
      Parameters:
        `key` - for Destinations or RouterIdentities

    - #### isNegativeCachedForever

          public boolean isNegativeCachedForever(Hash key)

      Is it permanently negative cached?
      Overrides:
        `isNegativeCachedForever` in class `NetworkDatabaseFacade`
      Parameters:
        `key` - only for Destinations; for RouterIdentities, see Banlist

    - #### isNewer

          public static boolean isNewer(LeaseSet a,
                                        LeaseSet b)

      Utility to determine if a is newer than b. Uses publish date if a and b are both LS2, else earliest lease date.
      Parameters:
        `a` - non-null
        `b` - non-null
      Returns:
        if a is newer than b

    - #### lookupBeforeDropping

          protected void lookupBeforeDropping(Hash peer,
                                              RouterInfo info)

      Don't use directly - see F.N.D.F. override

    - #### lookupDestination

          public void lookupDestination(Hash key,
                                        Job onFinishedJob,
                                        long timeoutMs,
                                        Hash fromLocalDest)

      Lookup using the client's tunnels Succeeds even if LS validation and store fails due to unsupported sig type, expired, etc. Note that there are not separate success and fail jobs. Caller must call lookupDestinationLocally() in the job to determine success.
      Specified by:
        `lookupDestination` in class `NetworkDatabaseFacade`
      Parameters:
        `onFinishedJob` - non-null
        `fromLocalDest` - use these tunnels for the lookup, or null for exploratory

    - #### lookupDestinationLocally

          public Destination lookupDestinationLocally(Hash key)

      Lookup locally in netDB and in badDest cache Succeeds even if LS validation fails due to unsupported sig type, expired, etc.
      Specified by:
        `lookupDestinationLocally` in class `NetworkDatabaseFacade`

    - #### lookupFailed

          void lookupFailed(Hash key)

      Increment in the negative lookup cache
      Parameters:
        `key` - for Destinations or RouterIdentities

    - #### lookupLeaseSet

          public void lookupLeaseSet(Hash key,
                                     Job onFindJob,
                                     Job onFailedLookupJob,
                                     long timeoutMs)

      Lookup using exploratory tunnels. Use lookupDestination() if you don't need the LS or don't need it validated.
      Specified by:
        `lookupLeaseSet` in class `NetworkDatabaseFacade`

    - #### lookupLeaseSet

          public void lookupLeaseSet(Hash key,
                                     Job onFindJob,
                                     Job onFailedLookupJob,
                                     long timeoutMs,
                                     Hash fromLocalDest)

      Lookup using the client's tunnels Use lookupDestination() if you don't need the LS or don't need it validated.
      Specified by:
        `lookupLeaseSet` in class `NetworkDatabaseFacade`
      Parameters:
        `fromLocalDest` - use these tunnels for the lookup, or null for exploratory

    - #### lookupLeaseSetLocally

          public LeaseSet lookupLeaseSetLocally(Hash key)

      Use lookupDestination() if you don't need the LS or don't need it validated.
      Specified by:
        `lookupLeaseSetLocally` in class `NetworkDatabaseFacade`

    - #### lookupLeaseSetRemotely

          public void lookupLeaseSetRemotely(Hash key,
                                             Hash fromLocalDest)

      Unconditionally lookup using the client's tunnels. No success or failed jobs, no local lookup, no checks. Use this to refresh a leaseset before expiration.
      Specified by:
        `lookupLeaseSetRemotely` in class `NetworkDatabaseFacade`
      Parameters:
        `fromLocalDest` - use these tunnels for the lookup, or null for exploratory

    - #### lookupLeaseSetRemotely

          public void lookupLeaseSetRemotely(Hash key,
                                             Job onFindJob,
                                             Job onFailedLookupJob,
                                             long timeoutMs,
                                             Hash fromLocalDest)

      Unconditionally lookup using the client's tunnels.
      Specified by:
        `lookupLeaseSetRemotely` in class `NetworkDatabaseFacade`
      Parameters:
        `fromLocalDest` - use these tunnels for the lookup, or null for exploratory
        `onFindJob` - may be null
        `onFailedLookupJob` - may be null

    - #### lookupLocally

          public DatabaseEntry lookupLocally(Hash key)

      Specified by:
        `lookupLocally` in class `NetworkDatabaseFacade`
      Returns:
        RouterInfo, LeaseSet, or null, validated

    - #### lookupLocallyWithoutValidation

          public DatabaseEntry lookupLocallyWithoutValidation(Hash key)

      Not for use without validation
      Specified by:
        `lookupLocallyWithoutValidation` in class `NetworkDatabaseFacade`
      Returns:
        RouterInfo, LeaseSet, or null, NOT validated

    - #### lookupRouterInfo

          public void lookupRouterInfo(Hash key,
                                       Job onFindJob,
                                       Job onFailedLookupJob,
                                       long timeoutMs)

      Specified by:
        `lookupRouterInfo` in class `NetworkDatabaseFacade`

    - #### lookupRouterInfoLocally

          public RouterInfo lookupRouterInfoLocally(Hash key)

      This will return immediately with the result or null. However, this may still fire off a lookup if the RI is present but expired (and will return null). This may result in deadlocks. For true local only, use lookupLocallyWithoutValidation()
      Specified by:
        `lookupRouterInfoLocally` in class `NetworkDatabaseFacade`
      Returns:
        null always for client dbs

    - #### publish

          public void publish(LeaseSet localLeaseSet)
                       throws IllegalArgumentException

      Publishes a local LeaseSet by storing it and scheduling republishing if applicable. Ensures LeaseSet expiry dates are valid (not expired before publish).
      Specified by:
        `publish` in class `NetworkDatabaseFacade`
      Parameters:
        `localLeaseSet` - the LeaseSet to publish
      Throws:
        `IllegalArgumentException` - if LeaseSet is invalid or expired

    - #### publish

          public void publish(RouterInfo localRouterInfo)
                       throws IllegalArgumentException

      Stores to local db only. Overridden in FNDF to actually send to the floodfills.
      Specified by:
        `publish` in class `NetworkDatabaseFacade`
      Throws:
        `IllegalArgumentException` - if the local router info is invalid or if this is a client DB

    - #### queueForExploration

          public void queueForExploration(Collection<Hash> keys)

    - #### registerPublishingJob

          boolean registerPublishingJob(RepublishLeaseSetJob job)

      Register a new job for tracking. Skips registration if a job is already active.
      Returns:
        true if job was registered, false if one was already active

    - #### removeBlindData

          public boolean removeBlindData(SigningPublicKey spk)

      For console ConfigKeyringHelper
      Overrides:
        `removeBlindData` in class `NetworkDatabaseFacade`
      Parameters:
        `spk` - the unblinded public key
      Returns:
        true if removed

    - #### removeFromExploreKeys

          public void removeFromExploreKeys(Collection<Hash> toRemove)

    - #### removePublishingJob

          void removePublishingJob(Hash hash,
                                   RepublishLeaseSetJob job)

      Remove a specific job from the tracking set.

    - #### renderStatusHTML

          public void renderStatusHTML(Writer out)
                                throws IOException

      Debug info, HTML formatted
      Specified by:
        `renderStatusHTML` in interface `Service`
      Overrides:
        `renderStatusHTML` in class `NetworkDatabaseFacade`
      Throws:
        `IOException`

    - #### rescan

          public void rescan()

      Overrides:
        `rescan` in class `NetworkDatabaseFacade`

    - #### reseedChecker

          public ReseedChecker reseedChecker()

      Returns the reseed checker for this database.
      Overrides:
        `reseedChecker` in class `NetworkDatabaseFacade`
      Returns:
        the ReseedChecker instance, or null if this is a client database

    - #### routerInfoPublishSuccessful

          void routerInfoPublishSuccessful()

      Set the last time we successfully published our RI.

    - #### routingKeyChanged

          public void routingKeyChanged()

      Notify the netDB that the routing key changed at midnight UTC
      Overrides:
        `routingKeyChanged` in class `NetworkDatabaseFacade`

    - #### search

          SearchJob search(Hash key,
                           Job onFindJob,
                           Job onFailedLookupJob,
                           long timeoutMs,
                           boolean isLease)

      Begin a kademlia style search for the key specified, which can take up to timeoutMs and will fire the appropriate jobs on success or timeout (or if the kademlia search completes without any match) Unused - called only by FNDF.searchFull() from FloodSearchJob which is overridden - don't use this.
      Throws:
        `UnsupportedOperationException` - always

    - #### search

          SearchJob search(Hash key,
                           Job onFindJob,
                           Job onFailedLookupJob,
                           long timeoutMs,
                           boolean isLease,
                           Hash fromLocalDest)

      Unused - see FNDF
      Throws:
        `UnsupportedOperationException` - always

    - #### searchComplete

          void searchComplete(Hash key)

      The search for the given key is no longer active

    - #### sendStore

          abstract void sendStore(Hash key,
                                  DatabaseEntry ds,
                                  Job onSuccess,
                                  Job onFailure,
                                  long sendTimeout,
                                  Set<Hash> toIgnore)

      See implementation in FNDF
      Parameters:
        `key` - the DatabaseEntry hash
        `onSuccess` - may be null, always called if we are ff and ds is an RI
        `onFailure` - may be null, ignored if we are ff and ds is an RI
        `sendTimeout` - ignored if we are ff and ds is an RI
        `toIgnore` - may be null, if non-null, all attempted and skipped targets will be added as of 0.9.53, unused if we are ff and ds is an RI

    - #### setBlindData

          public void setBlindData(BlindData bd)

      Overrides:
        `setBlindData` in class `NetworkDatabaseFacade`
      Parameters:
        `bd` - new BlindData to put in the cache

    - #### setLastExploreNewDate

          void setLastExploreNewDate(long when)

    - #### shutdown

          public void shutdown()

      Cannot be restarted.

    - #### startup

          public void startup()

      Description copied from interface: `Service`
      Instruct the service that it should start normal operation. This call DOES block until the service is ready.

    - #### stopPublishing

          void stopPublishing(Hash target)

    - #### store

          public LeaseSet store(Hash key,
                                LeaseSet leaseSet)
                         throws IllegalArgumentException

      Specified by:
        `store` in class `NetworkDatabaseFacade`
      Returns:
        the leaseSet if another leaseSet already existed at that key
      Throws:
        `IllegalArgumentException` - if the data is not valid

    - #### store

          public LeaseSet store(Hash key,
                                LeaseSet leaseSet,
                                boolean force)
                         throws IllegalArgumentException

      Store the leaseSet. If the store fails due to unsupported crypto, it will negative cache the hash until restart.
      Parameters:
        `force` - always store even if not newer
      Returns:
        previous entry or null
      Throws:
        `IllegalArgumentException` - if the leaseSet is not valid
        `UnsupportedCryptoException` - if that's why it failed.

    - #### store

          public RouterInfo store(Hash key,
                                  RouterInfo routerInfo)
                           throws IllegalArgumentException

      Store the routerInfo. If the store fails due to unsupported crypto, it will banlist the router hash until restart and then throw UnsupportedCrytpoException.
      Specified by:
        `store` in class `NetworkDatabaseFacade`
      Returns:
        previous entry or null
      Throws:
        `IllegalArgumentException` - if the routerInfo is not valid
        `UnsupportedCryptoException` - if that's why it failed.

    - #### store

          RouterInfo store(Hash key,
                           RouterInfo routerInfo,
                           boolean persist)
                    throws IllegalArgumentException

      Store the routerInfo. If the store fails due to unsupported crypto, it will banlist the router hash until restart and then throw UnsupportedCrytpoException.
      Returns:
        previous entry or null
      Throws:
        `IllegalArgumentException` - if the routerInfo is not valid
        `UnsupportedCryptoException` - if that's why it failed.

    - #### toString

          public String toString()

      Overrides:
        `toString` in class `Object`

    - #### unpublish

          public void unpublish(LeaseSet localLeaseSet)

      Specified by:
        `unpublish` in class `NetworkDatabaseFacade`

    - #### validate

          public String validate(Hash key,
                                 LeaseSet leaseSet)
                          throws UnsupportedCryptoException

      Validates whether the given LeaseSet is acceptable as valid and current based on current known parameters.

      This method performs several checks including:

      - Verifying the key matches the LeaseSet destination.
      - Validating the LeaseSet's cryptographic signature.
      - Checking if the LeaseSet is too old (expired).
      - Checking if the LeaseSet expires too far in the future.

      Note: Unlike RouterInfos, this validation is only done once at storage time. Afterward, `LeaseSet.isCurrent()` should be used to check currency.

      Parameters:
        `key` - the expected key (destination hash) for this LeaseSet
        `leaseSet` - the LeaseSet instance to validate
      Returns:
        a descriptive reason why the LeaseSet is invalid or expired, or `null` if the LeaseSet is valid
      Throws:
        `UnsupportedCryptoException` - if the LeaseSet uses an unsupported cryptographic type/signature

    - #### validate

          String validate(RouterInfo routerInfo)
                   throws IllegalArgumentException

      Determine whether this routerInfo will be accepted as valid and current given what we know now. Call this before each use, to check expiration
      Returns:
        reason why the entry is not valid, or null if it is valid
      Throws:
        `IllegalArgumentException`