rust-p2p / s-kademlia

Implementation of the s/kademlia protocol
9 stars 2 forks source link

NodeId <=> PublicKey #3

Closed 4meta5 closed 5 years ago

4meta5 commented 5 years ago

s-kademlia recommends adding additional requirements on id to artifically slow down an influx of new members. In practice, this doesn't really work.

At the moment, the key generate in key::KeyPai::new() does some really stupid thing where it loops until it only generates keys with a certain number of trailing zeros. This is dumb and I haven't spent a lot of time checking if "it works" (in an anti-sybil sense) because I don't really think this computational hardness is a sufficient anti-sybil mechanism.

I expect troublescooter's incentive research will help here. I need to configure some sort of NodeScore that manages all the data useful in describing the reputation of the Node. I might add this as a field to Node in node.rs.

recent thoughts

If our current node default trusts certain, long-living peers and the records recently (requires timestamp) received from those peers, then it should be able to gossip about those records in order to receive new information; it can discern how much information to share with the new node by verifying data on other existing nodes on the network. Conflicts in the records push the local node to query peers for the recent records and discern whether the conflicts are legitimate. If the queries are validated and the updates benefit the local storage of the node in question, the node in question should be more comfortable sharing more data with the new node.

4meta5 commented 5 years ago

I'm leaning towards code organization where I define a trait that is derived from hashing a PublicKey such that PublicKey could be multiple key types (define it as ed25519 first). One goal of any design would be to minimize the friction associated with converting the public key associated with an ID for message signing.

Some of these are more far fetched than others, but I am increasingly fond of allocating a few dynamic array-based stores as caches and overflow buffers to manage a more complex data store rather than pre-allocating some giant routing table.

4meta5 commented 5 years ago

This issue conflates anti-sybil research and identity type management (because they are very related under s-kademlia). For context, s-kademlia proposes checking for a trailing number of zeros to enforce some difficulty for generating NodeId, but I am not convinced this is sufficient. Maybe some benchmarks would make me more convinced that this makes sense in practice.

In the old KeyPair::new() method,

        let super_counter = SteadyTime::now()
        loop {
            let new_keypair = ed25519::Keypair::generate(&mut rand::thread_rng());
            let difficulty: u32 = 5; // number of required trailing zeros
            let counter = 0u32;
            let success = true;
            new_keypair.to_bytes().into_iter().rev().for_each(|i| {
                if counter < difficulty && i != 0 {
                    success = false;
                }
                counter += 1;
            });
            if success { return Ok(Keypair(new_keypair)) };
            super_counter += 1;
            if super_counter > timeout {
                return Err(AntiSybilError::new("Anti-sybil mechanism timed out"))
            }
        };

Doing this as part of KeyPair generation is not smart imo. There are presumably better ways of limiting how fast nodes can join the network => I'd be fine with restricted network assumptions and a limit on new joining nodes for any given time period. Maybe each existing node can allow some number of new nodes to join and this limit can be voted on by all the nodes participating in the network. Forward guidance for tolerance to new members according to vote by existing members.

4meta5 commented 5 years ago

closed in favor of #9