signed peer records: make them actually usable
To be able to retrieve signed peer records, we need to store the serialized format, thanks to their non-deterministic serialization. We also need to store the contents in the peer store, if we actually want to use the contents.
The current peer store API makes using signed peer records very cumbersome: https://github.com/libp2p/go-libp2p/blob/5a0411b8eba4276b907c21fefc3adebde19096f1/core/peerstore/peerstore.go#L123-L181
Most importantly, it doesn't allow us to filter addresses, it's all or nothing. This is a problem for #2300, and will be for Kademlia, once it adds support for signed peer records (see https://github.com/libp2p/go-libp2p-kad-dht/pull/839). In identify, we currently accept any signed peer record the peer sends us, without even checking that it's the peer's signed peer record (any correctly signed record will be accepted).
What we should do instead is the following:
- Remove the
CertifiedAddrBookinterface. - Use the regular
AddAddrsAPI to add save the addresses contained in the signed peer record. - Save the serialized bytes of the record in the metadata.
Metadata might not give us the properties we're looking for, we need to be able to atomically update the metadata iff we receive a new record with a higher sequence number.
This has be atomic since there will be multiple places from which such updates will happen (e.g. Identify, Kademlia, etc.).
Possible API:
type CertifiedAddrBook interface {
MaybeAddCertifiedRecord(p peer.ID, seq uint64, envelope []byte) (updated ok) // we only update when the sequence number is higher than what we're currently storing
GetCertifiedRecord(p peer.ID) []byte // nil if we don't have one
}
Can we move the address handling logic out and keep the peer record api as
type CertifiedAddrBook interface {
MaybeAddCertifiedPeerRecord(envelope *record.Envelope) (updated ok)
GetCertifiedRecord(p peer.ID) *record.Envelope
}
Related proposal to fully embrace signed peer records: https://github.com/libp2p/specs/issues/552