The first fix independently extends the address expiration time and the address
TTL:
By example:
* We have an address with a TTL of 4s that will expire in 1s.
* We update it with a TTL of 3s.
Before this change:
* We end up with an address with a TTL of 3s that will expire in 3s.
After this change:
* We end up with an address with a TTL of 4s that will expire in 3s.
---
The second fix prevents the in-memory addressbook from announcing existing
addresses every time their TTLs get updated.
---
The third fix correctly updates TTLs for existing addresses in the on-disk
addressbook.
This fixes https://github.com/libp2p/go-libp2p-identify/issues/2
The GC procedure consists of two tiers: lookahead and purge. The
lookahead tier runs less frequently (default 12 hours) than the purge
tier (default 5 minutes).
A lookahead round traverses the entire store and picks entries that
need to be visited in the current lookahead window, pinning those
entries in a separate region in the KV store, indexed by the next visit
timestamp.
A purge round iterates over the lookahead window only, and refreshes
the entries that require a visit. It removes them from the lookahead
region unless the entry requires another visit within the current
window.
Introduces custom types in protobuf to serde directly into multiaddrs
and peer IDs. Simplify purge by ordering addrs by expiry. In general,
getting this readier for merge.
Each entry in the address book KV store now represents a full peer
with all its addresses. Expiries and TTLs are kept inline. Records are
serialised with Protobuf.
Housekeeping is performed on retrieve, and via a periodic GC routine.
The architecture mimics a write-through cache, although not strictly.
This is a "more correct" API and we might as well fix this before it becomes
used all over the place. The new API returns ErrNoPublicKey when there is no
inlined key.
This *also* fixes a bug where the datastore-backed keystore would panic if
`ExtractPublicKey` returned `nil, nil`.