Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kad: Expose all peer records of GET_VALUE query #96

Merged
merged 10 commits into from May 16, 2024

Conversation

lexnv
Copy link
Collaborator

@lexnv lexnv commented Apr 29, 2024

This PR extends the GetRecordSucess variant of kad queries to provide all the query information.
Previously, only the last stored query record was returned to the user.

In the libp2p crate, an event is generated for every found record. However, litep2p responds only when the query finishes.
Records are extended to offer similar information back to the user while sending a minimum number of events.

  • A new RecordsType is introduced to avoid confusion about records extracted from the local store and records found on the network
  • We save the record backed by the most number of peers in our local store
  • A panic is removed from the kad/query since we now operate with a multitude of records and potentially none
  • Expired records are now ignored

cc @paritytech/networking

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
@lexnv lexnv changed the title kad: Expose all peer records of FIND_VALUE query kad: Expose all peer records of GET_VALUE query Apr 29, 2024
@lexnv lexnv self-assigned this Apr 29, 2024
@@ -52,6 +52,8 @@ pub use handle::{KademliaEvent, KademliaHandle, Quorum, RoutingTableUpdateMode};
pub use query::QueryId;
pub use record::{Key as RecordKey, PeerRecord, Record};

use self::handle::RecordsType;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pub, so we can use this type to deconstruct it, or maybe we can try to keep the libp2p semantics for PeerRecord and we don't need this extra type:

/// A record either received by the given peer or retrieved from the local
/// record store.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PeerRecord {
    /// The peer from whom the record was received. `None` if the record was
    /// retrieved from local storage.
    pub peer: Option<PeerId>,
    pub record: Record,
}

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
alexggh added a commit to paritytech/polkadot-sdk that referenced this pull request Apr 30, 2024
Signed-off-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>
github-merge-queue bot pushed a commit to paritytech/polkadot-sdk that referenced this pull request May 2, 2024
This PR updates the litep2p crate to the latest version.

This fixes the build for developers that want to perform `cargo update`
on all their dependencies:
#4343, by porting the
latest changes.

The peer records were introduced to litep2p to be able to distinguish
and update peers with outdated records.
It is going to be properly used in substrate via:
#3786, however that is
pending the commit to merge on litep2p master:
paritytech/litep2p#96.

Closes: #4343

---------

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
jmg-duarte pushed a commit to eigerco/polkadot-sdk that referenced this pull request May 8, 2024
This PR updates the litep2p crate to the latest version.

This fixes the build for developers that want to perform `cargo update`
on all their dependencies:
paritytech#4343, by porting the
latest changes.

The peer records were introduced to litep2p to be able to distinguish
and update peers with outdated records.
It is going to be properly used in substrate via:
paritytech#3786, however that is
pending the commit to merge on litep2p master:
paritytech/litep2p#96.

Closes: paritytech#4343

---------

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Copy link
Collaborator

@dmitry-markin dmitry-markin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Comment on lines 642 to 654
// Considering this gives a view of all peers and their records, some peers may have
// outdated records. Store only the record which is backed by most
// peers.
let rec = records
.iter()
.map(|peer_record| &peer_record.record)
.fold(HashMap::new(), |mut acc, rec| {
*acc.entry(rec).or_insert(0) += 1;
acc
})
.into_iter()
.max_by_key(|(_, v)| *v)
.map(|(k, _)| k);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to have tests for correctly updating the local store and also discarding the expired records. At least as a follow-up planned / TODO issue if it's too much work to implement straight away.

bgallois pushed a commit to duniter/duniter-polkadot-sdk that referenced this pull request May 10, 2024
This PR updates the litep2p crate to the latest version.

This fixes the build for developers that want to perform `cargo update`
on all their dependencies:
paritytech#4343, by porting the
latest changes.

The peer records were introduced to litep2p to be able to distinguish
and update peers with outdated records.
It is going to be properly used in substrate via:
paritytech#3786, however that is
pending the commit to merge on litep2p master:
paritytech/litep2p#96.

Closes: paritytech#4343

---------

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
koushiro pushed a commit to koushiro-contrib/polkadot-sdk that referenced this pull request May 11, 2024
This PR updates the litep2p crate to the latest version.

This fixes the build for developers that want to perform `cargo update`
on all their dependencies:
paritytech#4343, by porting the
latest changes.

The peer records were introduced to litep2p to be able to distinguish
and update peers with outdated records.
It is going to be properly used in substrate via:
paritytech#3786, however that is
pending the commit to merge on litep2p master:
paritytech/litep2p#96.

Closes: paritytech#4343

---------

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
lexnv added 3 commits May 16, 2024 13:58
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
@lexnv
Copy link
Collaborator Author

lexnv commented May 16, 2024

Thanks @dmitry-markin for the review 🙏

I've added to tests to validate the kademlia behavior in this case:

  • one test to see that the record backed by most peers is added to the local storage
  • one test to ensure that expired records don't count towards the records frequency

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
@lexnv lexnv merged commit 423a35d into master May 16, 2024
8 checks passed
@lexnv lexnv deleted the lenxv/expose-peer-records branch May 16, 2024 11:16
lexnv added a commit that referenced this pull request May 16, 2024
This PR refactors the `GetRecord` query to make it more robust.
- Avoid panics on unwraps and unimplemented logic
- Separate config immutable variables from main query logic
- Simplifies logic of `next_action` method 
- Private methods for internal logic

Builds on top of: #96

cc @paritytech/networking

---------

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
@lexnv lexnv mentioned this pull request May 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants