net.i2p.data

## Class DatabaseEntry

- java.lang.Object
- - net.i2p.data.DataStructureImpl
  - - net.i2p.data.DatabaseEntry

- All Implemented Interfaces:
    Serializable, DataStructure
  Direct Known Subclasses:
    LeaseSet, RouterInfo

      public abstract class DatabaseEntry
      extends DataStructureImpl

  Base class for data structures stored in the I2P network database (NetDb).

  DatabaseEntry provides common infrastructure for NetDb-storable objects:

  - Core Types: Base for `LeaseSet` and `RouterInfo`
  - Unified Interface: Simplifies NetDB and I2NP implementation
  - Common Operations: Shared methods for hashing, routing, and signing
  - Integrity Protection: Prevents modification after signing

  Key Features:

  - SHA-256 Hash: Unique identifier for database storage and lookup
  - Routing Key: Modified hash for distributed hash Table (DHT) routing
  - Timestamp: Creation or last-modified time for cache management
  - Signatures: Cryptographic signatures for authenticity verification
  - Type Constants: Standardized type identifiers for all NetDb entries

  Supported Entry Types:

  - `KEY_TYPE_ROUTERINFO` - Router information and capabilities
  - `KEY_TYPE_LEASESET` - Legacy LeaseSet format
  - `KEY_TYPE_LS2` - Modern LeaseSet2 format
  - `KEY_TYPE_META_LS2` - MetaLeaseSet for advanced routing

  Integrity Protection:

  - Immutable After Signing: Objects cannot be modified once signed
  - IllegalStateException: Thrown when modification is attempted
  - NetDb Protection: Prevents corruption of network database
  - Message Safety: Protects I2NP messages from tampering

  Usage Patterns:

  - Network Storage: Entries stored in distributed hash table
  - Lookup Operations: Fast retrieval by hash or routing key
  - Cache Management: Timestamp-based expiration and refresh
  - Floodfill: Distribution of new and updated entries

  Security Considerations:

  - Signature Verification: Always verify before trusting entries
  - Timestamp Validation: Check for stale or expired entries
  - Hash Collision: Verify SHA-256 hash matches content
  - Routing Key Security: Protect against routing attacks

  Implementation Notes:

  - 0.8.2: Initial implementation with retrofitting
  - Code Consolidation: Reduces instanceof usage throughout codebase
  - Thread Safety: Protection not guaranteed to be thread-safe
  - Object Reuse: Do not reuse DatabaseEntry instances

  Warning:

  - Direct Modification: Avoid modifying internal byte[] objects
  - Corruption Avenues: Multiple paths can bypass protection
  - Careful Usage: Protection is not foolproof against all attacks
  See Also:
    Serialized Form

- - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `protected Signature` | `_signature`
    `static int` | `KEY_TYPE_ENCRYPTED_LS2` Encrypted LeaseSet 2 type.
    `static int` | `KEY_TYPE_LEASESET`
    `static int` | `KEY_TYPE_LS2` LeaseSet 2 type.
    `static int` | `KEY_TYPE_META_LS2` Meta LeaseSet 2 type.
    `static int` | `KEY_TYPE_ROUTERINFO` these are the same as in i2np's DatabaseStoreMessage
    `static int` | `KEY_TYPE_SERVICE_LIST` Service list type.
    `static int` | `KEY_TYPE_SERVICE_RECORD` Service record type.

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `DatabaseEntry()`

  - ### Method Summary

    All Methods Static Methods Instance Methods Abstract Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `protected abstract byte[]` | `getBytes()` Returns the raw payload data, excluding the signature, to be signed by sign().
    `abstract long` | `getDate()` A common interface to the timestamp of the two subclasses.
    `Hash` | `getHash()` A common interface to the Hash of the two subclasses.
    `abstract KeysAndCert` | `getKeysAndCert()` Get the keys and the cert Identical to getDestination() in LeaseSet, and getIdentity() in RouterInfo.
    `boolean` | `getReceivedAsPublished()` If true, we received this LeaseSet by a remote peer publishing it to us, rather than by searching for it ourselves or locally creating it.
    `boolean` | `getReceivedAsReply()` If true, we received this LeaseSet by searching for it Default false.
    `Hash` | `getReceivedBy()` The Hash of the local client that received this LS, null if the router or unknown.
    `Hash` | `getRoutingKey()` Get the routing key for the structure using the current modifier in the RoutingKeyGenerator.
    `Signature` | `getSignature()` Retrieve the proof that the identity stands behind the info here
    `protected SigningPublicKey` | `getSigningPublicKey()` Identical to getDestination().getSigningPublicKey() in LeaseSet, and getIdentity().getSigningPublicKey() in RouterInfo.
    `abstract int` | `getType()` Get the type of the data structure.
    `boolean` | `isLeaseSet()` Convenience method, is the type any variant of leaseset?
    `static boolean` | `isLeaseSet(int type)` Convenience method, is the type any variant of leaseset?
    `boolean` | `isRouterInfo()` Convenience method, is the type any variant of router info?
    `void` | `setReceivedAsPublished()` Marks this entry as received via published mode.
    `void` | `setReceivedAsReply()` set to true
    `void` | `setReceivedBy(Hash receivedBy)` Sets the local client that received this entry.
    `void` | `setSignature(Signature signature)` Configure the proof that the entity stands behind the info here
    `void` | `sign(SigningPrivateKey key)` Sign the structure using the supplied signing key
    `boolean` | `validateRoutingKey()` Validates the routing key for this entry.
    `boolean` | `verifySignature()` This is the same as isValid() in RouterInfo or verifySignature() in LeaseSet.

    - ### Methods inherited from class net.i2p.data.DataStructureImpl

      `calculateHash, fromBase64, fromByteArray, read, toBase64, toByteArray`

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

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

    - ### Methods inherited from interface net.i2p.data.DataStructure

      `readBytes, writeBytes`

- - ### Field Detail

    - #### _signature

          protected volatile Signature _signature

    - #### KEY_TYPE_ENCRYPTED_LS2

          public static final int KEY_TYPE_ENCRYPTED_LS2

      Encrypted LeaseSet 2 type.
      See Also:
        Constant Field Values

    - #### KEY_TYPE_LEASESET

          public static final int KEY_TYPE_LEASESET

      See Also:
        Constant Field Values

    - #### KEY_TYPE_LS2

          public static final int KEY_TYPE_LS2

      LeaseSet 2 type.
      See Also:
        Constant Field Values

    - #### KEY_TYPE_META_LS2

          public static final int KEY_TYPE_META_LS2

      Meta LeaseSet 2 type.
      See Also:
        Constant Field Values

    - #### KEY_TYPE_ROUTERINFO

          public static final int KEY_TYPE_ROUTERINFO

      these are the same as in i2np's DatabaseStoreMessage
      See Also:
        Constant Field Values

    - #### KEY_TYPE_SERVICE_LIST

          public static final int KEY_TYPE_SERVICE_LIST

      Service list type.
      See Also:
        Constant Field Values

    - #### KEY_TYPE_SERVICE_RECORD

          public static final int KEY_TYPE_SERVICE_RECORD

      Service record type.
      See Also:
        Constant Field Values

  - ### Constructor Detail

    - #### DatabaseEntry

          public DatabaseEntry()

  - ### Method Detail

    - #### getBytes

          protected abstract byte[] getBytes()
                                      throws DataFormatException

      Returns the raw payload data, excluding the signature, to be signed by sign(). Most callers should use writeBytes() or toByteArray() instead.
      Returns:
        the raw payload data, or null on error (for example, if this is a RouterInfo, a DataFormatException is thrown instead)
      Throws:
        `DataFormatException`

    - #### getDate

          public abstract long getDate()

      A common interface to the timestamp of the two subclasses. Identical to getEarliestLeaseDate() in LeaseSet, and getPublished() in RouterInfo. Note that for a LeaseSet this will be in the future, and for a RouterInfo it will be in the past. Either way, it's a timestamp.

    - #### getHash

          public Hash getHash()

      A common interface to the Hash of the two subclasses. Identical to getDestination().calculateHash() in LeaseSet, and getIdentity().getHash() in RouterInfo.
      Returns:
        Hash or null

    - #### getKeysAndCert

          public abstract KeysAndCert getKeysAndCert()

      Get the keys and the cert Identical to getDestination() in LeaseSet, and getIdentity() in RouterInfo.
      Returns:
        KAC or null

    - #### getReceivedAsPublished

          public boolean getReceivedAsPublished()

      If true, we received this LeaseSet by a remote peer publishing it to us, rather than by searching for it ourselves or locally creating it. Default false.

    - #### getReceivedAsReply

          public boolean getReceivedAsReply()

      If true, we received this LeaseSet by searching for it Default false.

    - #### getReceivedBy

          public Hash getReceivedBy()

      The Hash of the local client that received this LS, null if the router or unknown.

    - #### getRoutingKey

          public Hash getRoutingKey()

      Get the routing key for the structure using the current modifier in the RoutingKeyGenerator. This only calculates a new one when necessary though (if the generator's key modifier changes)
      Throws:
        `IllegalStateException` - if not in RouterContext

    - #### getSignature

          public Signature getSignature()

      Retrieve the proof that the identity stands behind the info here

    - #### getSigningPublicKey

          protected SigningPublicKey getSigningPublicKey()

      Identical to getDestination().getSigningPublicKey() in LeaseSet, and getIdentity().getSigningPublicKey() in RouterInfo.
      Returns:
        SPK or null

    - #### getType

          public abstract int getType()

      Get the type of the data structure. This should be faster than instanceof.
      Returns:
        KEY_TYPE_ROUTERINFO or KEY_TYPE_LEASESET or LS2 types

    - #### isLeaseSet

          public boolean isLeaseSet()

      Convenience method, is the type any variant of leaseset?
      Returns:
        true for any type of LeaseSet, false for RouterInfo, false for others

    - #### isLeaseSet

          public static boolean isLeaseSet(int type)

      Convenience method, is the type any variant of leaseset?
      Returns:
        true for any type of LeaseSet, false for RouterInfo, false for others

    - #### isRouterInfo

          public boolean isRouterInfo()

      Convenience method, is the type any variant of router info?
      Returns:
        true for any type of RouterInfo, false for LeaseSet, false for others

    - #### setReceivedAsPublished

          public void setReceivedAsPublished()

      Marks this entry as received via published mode.

    - #### setReceivedAsReply

          public void setReceivedAsReply()

      set to true

    - #### setReceivedBy

          public void setReceivedBy(Hash receivedBy)

      Sets the local client that received this entry.

    - #### setSignature

          public void setSignature(Signature signature)

      Configure the proof that the entity stands behind the info here
      Throws:
        `IllegalStateException` - if already signed

    - #### sign

          public void sign(SigningPrivateKey key)
                    throws DataFormatException

      Sign the structure using the supplied signing key
      Throws:
        `IllegalStateException` - if already signed
        `DataFormatException`

    - #### validateRoutingKey

          public boolean validateRoutingKey()

      Validates the routing key for this entry.
      Throws:
        `IllegalStateException` - if not in RouterContext

    - #### verifySignature

          public boolean verifySignature()

      This is the same as isValid() in RouterInfo or verifySignature() in LeaseSet.
      Returns:
        valid