ChainSafe / ChainSafe/gossamer
Implement `put_record_to` in `go-libp2p-kad-dht`
- Dominant language
- Go
- Stars
- 454
- Forks
- 144
- PR merge metrics
- No merged PRs in 30d
Description
## From design doc:
#### `NetworkProvider`
Within Authority Discover a trait named [`NetworkProvider`] is defined as:
```rust
/// NetworkProvider provides [`Worker`] with all necessary hooks into the
/// underlying Substrate networking. Using this trait abstraction instead of
/// `sc_network::NetworkService` directly is necessary to unit test [`Worker`].
pub trait NetworkProvider:
NetworkDHTProvider + NetworkStateInfo + NetworkSigner + Send + Sync
{
}
```
I've copied all of `NetworkDHTProvider`, `NetworkStateInfo` and `NetworkSigner` traits below:
```rust
/// Provides access to the networking DHT.
pub trait NetworkDHTProvider {
/// Start getting a value from the DHT.
fn get_value(&self, key: &KademliaKey);
/// Start putting a value in the DHT.
fn put_value(&self, key: KademliaKey, value: Vec);
/// Start putting the record to `peers`.
///
/// If `update_local_storage` is true the local storage is udpated as well.
fn put_record_to(&self, record: Record, peers: HashSet, update_local_storage: bool);
/// Store a record in the DHT memory store.
fn store_record(
&self,
key: KademliaKey,
value: Vec,
publisher: Option,
expires: Option,
);
/// Register this node as a provider for `key` on the DHT.
fn start_providing(&self, key: KademliaKey);
/// Deregister this node as a provider for `key` on the DHT.
fn stop_providing(&self, key: KademliaKey);
/// Start getting the list of providers for `key` on the DHT.
fn get_providers(&self, key: KademliaKey);
}
```
For `NetworkDHTProvider` functionality the current `go-libp2p-kad-dht` implementation supports everything except `store_record`. This is a function that exists in the `rust-libp2p` library. Essentially, it is a directed message to a peer to update the expiry for that key/value. This is used in `Worker` to update authority records on other known peers.
```rust
/// Trait for providing information about the local network state
pub trait NetworkStateInfo {
/// Returns the local external addresses.
fn external_addresses(&self) -> Vec;
/// Returns the listening addresses (without trailing `/p2p/` with our `PeerId`).
fn listen_addresses(&self) -> Vec;
/// Returns the local Peer ID.
fn local_peer_id(&self) -> PeerId;
}
```
The `NetworkStateInfo` trait/interface can be be implemented by calling existing Gossamer code.
```rust
/// Signer with network identity
pub trait NetworkSigner {
/// Signs the message with the `KeyPair` that defines the local [`PeerId`].
fn sign_with_local_identity(&self, msg: Vec) -> Result;
/// Verify signature using peer's public key.
///
/// `public_key` must be Protobuf-encoded ed25519 public key.
///
/// Returns `Err(())` if public cannot be parsed into a valid ed25519 public key.
fn verify(
&self,
peer_id: sc_network_types::PeerId,
public_key: &Vec,
signature: &Vec,
message: &Vec,
) -> Result;
}
```
The `NetworkSigner` trait/interface can be implemented by calling existing Gossamer code.
#### Implementing `NetworkDhtProvider`
I believe will we need to fork `go-libp2p-kad-dht` or look for viable alternatives DHT packages to support the `put_record_to` functionality. Without this functionality we will not be able to run the Substrate Authority Discovery protocol as expected by Substrate based nodes. Given the `put_record_to` method is updating existing records based on creation time to specific peers, we will need to expose the message sender in `IpfsDHT` and add the functionality to a wrapper type, or add the function to it and hope to merge back upstream.
## Acceptance Criteria
- Implement `put_record_to` functionality in fork of `go-libp2p-kad-dht`
- Unit tests
- PR back to upstream
[`Worker`]:https://github.com/paritytech/polkadot-sdk/blob/4b054c60b1641612ef0a76dcc75eed5dd23a18cf/substrate/client/authority-discovery/src/worker.rs#L233
[`Service`]:https://github.com/paritytech/polkadot-sdk/blob/414a8fc2eda3bb72e30cefdba628cf6c361cd6e1/substrate/client/authority-discovery/src/service.rs#L34
[`Role`]:https://github.com/paritytech/polkadot-sdk/blob/4b054c60b1641612ef0a76dcc75eed5dd23a18cf/substrate/client/authority-discovery/src/worker.rs#L86
[`AuthorityDiscovery`]:https://github.com/paritytech/polkadot-sdk/blob/4b054c60b1641612ef0a76dcc75eed5dd23a18cf/substrate/client/authority-discovery/src/worker.rs#L205
[`ProvideRuntimeApi`]:https://github.com/paritytech/polkadot-sdk/blob/c5444f381fdba68aa9cb73b39cc63f34604da156/substrate/primitives/api/src/lib.rs#L750
[`HeaderBackend`]:https://github.com/paritytech/polkadot-sdk/blob/fdb4554e26ebdd4d729158501a3ddb3c6ebdfb6f/substrate/primitives/blockchain/src/backend.rs#L37
[`NetworkProvider`]:https://github.com/paritytech/polkadot-sdk/blob/4b054c60b1641612ef0a76dcc75eed5dd23a18cf/substrate/client/authority-discovery/src/worker.rs#L1029
[`DhtEvent`]:https://github.com/paritytech/polkadot-sdk/blob/4b054c60b1641612ef0a76dcc75eed5dd23a18cf/substrate/client/network/src/event.rs#L35
[`Service`]:https://github.com/paritytech/polkadot-sdk/blob/414a8fc2eda3bb72e30cefdba628cf6c361cd6e1/substrate/client/authority-discovery/src/service.rs#L34
[`ServicetoWorkerMessage`]:https://github.com/paritytech/polkadot-sdk/blob/80616f6d03661106326b621e9cc3ee1d2fa283ed/substrate/client/authority-discovery/src/lib.rs#L168
Contributor guide
Assessment
This issue has not been assessed yet.