java.lang.Object
net.i2p.router.JobImpl
net.i2p.router.networkdb.kademlia.FloodfillVerifyStoreJob
All Implemented Interfaces:
Job

class FloodfillVerifyStoreJobextends JobImpl
Two-phase floodfill store verification.

Phase 1 queries the peer we stored to, confirming it still holds a fresh entry (store acceptance that outlives the DSM reply). Phase 2 waits longer for the flood to propagate, then queries a different floodfill. A missing or stale reply in phase 2 is retried once against the same peer before blaming the store and flooding again — a single under-aged sample must not condemn a flood that is merely in flight.

  • Field Details

    • _log

      private final Log _log
      Logger for the verification job.
    • _banLogger

      private final BanLogger _banLogger
      Records why routers were banned.
    • _key

      private final Hash _key
      The key being verified.
    • _client

      private final Hash _client
      The client that published the data.
    • _target

      private volatile Hash _target
      The floodfill currently holding the data.
    • _sentTo

      private final Hash _sentTo
      The floodfill the query was sent to.
    • _facade

      private final FloodfillNetworkDatabaseFacade _facade
      The floodfill netdb we serve.
    • _expiration

      private long _expiration
      When the verified data expires.
    • _sendTime

      private long _sendTime
      When the current query was sent.
    • _attempted

      private int _attempted
      Floodfills queried so far.
    • _published

      private final long _published
      When the client published the data.
    • _type

      private final int _type
      The message type used for the query.
    • _isRouterInfo

      private final boolean _isRouterInfo
      True if verifying a router info.
    • _isLS2

      private final boolean _isLS2
      True if verifying an LS2 lease set.
    • _wrappedMessage

      private MessageWrapper.WrappedMessage _wrappedMessage
      The reply being verified.
    • _ignore

      private final Set<Hash> _ignore
      Floodfills not to query again.
    • _ipSet

      private final MaskedIPSet _ipSet
      Masked IPs of floodfills already tried.
    • PHASE_STORE_CHECK

      private static final int PHASE_STORE_CHECK
      Phase 1: confirm the store peer still has the entry.
      See Also:
    • PHASE_FLOOD_CHECK

      private static final int PHASE_FLOOD_CHECK
      Phase 2: confirm a different floodfill received the flood.
      See Also:
    • _phase

      private int _phase
      Current phase of the verification.
    • _floodRetried

      private boolean _floodRetried
      One same-peer flood-check retry already spent.
    • _requerySame

      private boolean _requerySame
      Keep the current phase-2 target instead of picking a new one.
    • _created

      private final long _created
      When this verify job was created (store success time).
    • _phase1DelayMs

      private final long _phase1DelayMs
      Delay before the first verification phase.
    • _phase2DelayMs

      private final long _phase2DelayMs
      Delay before the second verification phase.
    • _retryDelayMs

      private final long _retryDelayMs
      Delay before retrying a query.
    • PROP_PHASE1_DELAY

      private static final String PROP_PHASE1_DELAY
      Config key for the first phase delay.
      See Also:
    • PROP_PHASE2_DELAY_LS

      private static final String PROP_PHASE2_DELAY_LS
      Config key for the lease set phase 2 delay.
      See Also:
    • PROP_PHASE2_DELAY_RI

      private static final String PROP_PHASE2_DELAY_RI
      Config key for the router info phase 2 delay.
      See Also:
    • PROP_RETRY_DELAY

      private static final String PROP_RETRY_DELAY
      Config key for the query retry delay.
      See Also:
    • DEFAULT_PHASE1_DELAY

      private static final int DEFAULT_PHASE1_DELAY
      Default delay before the first phase.
      See Also:
    • DEFAULT_PHASE2_DELAY_LS

      private static final int DEFAULT_PHASE2_DELAY_LS
      Default phase 2 delay for lease sets.
      See Also:
    • DEFAULT_PHASE2_DELAY_RI

      private static final int DEFAULT_PHASE2_DELAY_RI
      Default phase 2 delay for router infos.
      See Also:
    • DEFAULT_RETRY_DELAY

      private static final int DEFAULT_RETRY_DELAY
      Default delay before a retry.
      See Also:
    • VERIFY_TIMEOUT

      private static final int VERIFY_TIMEOUT
      Total time allowed for one verification.
      See Also:
    • MAX_PEERS_TO_TRY

      private static final int MAX_PEERS_TO_TRY
      Floodfills queried for one verification.
      See Also:
    • IP_CLOSE_BYTES

      private static final int IP_CLOSE_BYTES
      Leading address bytes that count as a close IP.
      See Also:
    • RATES

      private static final long[] RATES
      Rate stat periods for the verification statistics.
  • Constructor Details

    • FloodfillVerifyStoreJob

      public FloodfillVerifyStoreJob(RouterContext ctx, Hash key, Hash client, long published, int type, Hash sentTo, Set<Hash> toSkip, FloodfillNetworkDatabaseFacade facade)
      Delay, then confirm the store peer still holds the entry; after a longer delay, confirm a different floodfill got the flood.
      Parameters:
      ctx - the router context
      key - the hash of the store entry being verified
      client - generally the same as key, unless encrypted LS2; non-null
      published - getDate() for RI or LS1, getPublished() for LS2
      type - the database entry type
      sentTo - who to give the credit or blame to, can be null
      toSkip - don't query any of these peers, may be null
      facade - the floodfill network database facade
  • Method Details

    • classifyStoreCheck

      static FloodfillVerifyStoreJob.StoreCheckResult classifyStoreCheck(boolean isStoreMsg, boolean entryFresh)
      Classify a phase-1 reply from the store peer.
      Parameters:
      isStoreMsg - true if the reply was a DatabaseStoreMessage, false for a search reply
      entryFresh - true if the entry's date/published is at least what we stored
      Returns:
      the store-check result
    • storeCheckFailed

      static boolean storeCheckFailed(FloodfillVerifyStoreJob.StoreCheckResult result)
      Whether phase 1 proved the store failed (missing or stale at the peer we stored to). An indeterminate result must not blame the store peer.
      Parameters:
      result - phase-1 classification
      Returns:
      true if verify should fail immediately and resend
    • classifyFloodCheck

      static FloodfillVerifyStoreJob.FloodCheckResult classifyFloodCheck(boolean isStoreMsg, boolean entryFresh)
      Classify a phase-2 reply from the alternate floodfill.
      Parameters:
      isStoreMsg - true if the reply was a DatabaseStoreMessage, false for a search reply
      entryFresh - true if the entry's date/published is at least what we stored
      Returns:
      the flood-check result
    • shouldRetryFloodCheck

      static boolean shouldRetryFloodCheck(FloodfillVerifyStoreJob.FloodCheckResult result, boolean alreadyRetried)
      Whether to re-query the same phase-2 peer once before blaming. Missing and stale are the only retryable outcomes, and only on the first miss.
      Parameters:
      result - phase-2 classification
      alreadyRetried - true if a same-peer retry was already performed
      Returns:
      true to schedule a retry against the same target
    • phase2StartTime

      static long phase2StartTime(long createdMs, long phase2DelayMs)
      Absolute time phase 2 may start, relative to verify-job creation.
      Parameters:
      createdMs - when the verify job was created
      phase2DelayMs - configured flood-check delay
      Returns:
      epoch ms at which the flood check may begin
    • clampDelay

      private static long clampDelay(long configured, int fallback)
      Reject nonsensical delay properties so a bad config cannot busy-loop.
      Parameters:
      configured - value from the router config
      fallback - default to use when configured is out of range
      Returns:
      a delay between 0 and 2 minutes
    • getName

      public String getName()
      Description copied from interface: Job
      Descriptive name of the task.
      Returns:
      the descriptive name of the task
    • runJob

      public void runJob()
      Run the current phase: first ask the peer we stored to, then a different floodfill after the flood-check delay has elapsed.

      Phase 1 failure (missing/stale at the store peer) resends immediately. Phase 2 missing/stale retries the same peer once, then resends.

    • enterFloodCheck

      private void enterFloodCheck()
      Leave the store-peer check and schedule the flood check at created + phase2 delay (immediately if that time already passed). Does not release the verify-in-progress slot.
    • scheduleFloodRetry

      private void scheduleFloodRetry()
      Re-query the same phase-2 peer after the retry delay (one shot). Does not release the verify-in-progress slot.
    • pickTarget

      private Hash pickTarget()
      Pick a responsive floodfill close to the key, but not the one we sent to.
      Returns:
      the floodfill to verify against; falls back to the floodfill we already stored to when no other peer is available
    • buildLookup

      private DatabaseLookupMessage buildLookup(TunnelInfo replyTunnelInfo)
      Builds the database lookup message for verification.
      Parameters:
      replyTunnelInfo - the tunnel to receive the reply on, source of the reply tunnel id and the From field
      Returns:
      non-null
    • isFresh

      private boolean isFresh(DatabaseEntry entry)
      Is the entry at least as new as what we published?
      Parameters:
      entry - entry the floodfill returned, compared against what we published
      Returns:
      true if fresh enough to count as success
    • finishVerify

      private void finishVerify()
      Release the verify-in-progress slot for this key.
    • banBadEntry

      private void banBadEntry(long delayMs)
      Ban a peer that returned an entry with a bad signature, then fail.
      Parameters:
      delayMs - reply latency for stats
    • failStoreCheck

      private void failStoreCheck(FloodfillVerifyStoreJob.StoreCheckResult result, long delayMs)
      Store-peer said the entry is missing or stale — the store itself failed. Blame only the store peer, then resend. No alternate peer was queried yet.
      Parameters:
      result - never FRESH or INDETERMINATE
      delayMs - reply latency for stats
    • succeedFloodCheck

      private void succeedFloodCheck(long delayMs)
      Full success: a different floodfill holds a fresh copy — the flood worked.
      Parameters:
      delayMs - reply latency for stats
    • failFloodCheck

      private void failFloodCheck(FloodfillVerifyStoreJob.FloodCheckResult result, long delayMs)
      Phase 2 still missing or stale after any retry — blame store peer for not flooding and the verify peer for not having it, then resend.
      Parameters:
      result - FRESH is not a failure
      delayMs - reply latency for stats
    • handleSearchReply

      private void handleSearchReply(DatabaseSearchReplyMessage dsrm, long delayMs)
      Handle a search reply (peer does not have the key) for the current phase.
      Parameters:
      dsrm - the search reply
      delayMs - reply latency for stats
    • handleStoreMessage

      private void handleStoreMessage(DatabaseEntry entry, long delayMs)
      Handle a store message (entry present) for the current phase.
      Parameters:
      entry - the entry from the reply
      delayMs - reply latency for stats
    • resend

      private void resend()
      The netDb store failed to verify, so resend it to a random floodfill peer Fixme - since we now store closest-to-the-key, this is likely to store to the very same ff as last time, until the stats get bad enough to switch. Therefore, pass the failed ff through as a don't-store-to. Let's also add the one we just tried to verify with, as they could be a pair of no-flooders. So at least we'll try THREE ffs round-robin if things continue to fail...