7

Nodes in the Ethereum P2P network assign their peers reputation in order to keep track of how well they behaved in the past and evaluate whether it would be preferable to disconnect from them.

What are the exact rules applied by Geth, Parity, and/or other clients to determine a peer's reputation? In particular, is being honest sufficient to get a good or even optimal reputation or is usefulness required for this as well?

Under what condition do peers disconnect? Is reputation remembered beyond the lifetime of a connection and used for peer selection (for instance in order to prevent immediate reconnects by bad peers)?

The only piece of documentation on that topic that I was able to find is this excerpt from the documentation of the NewBlockHashes message type:

Including hashes that the sending peer could reasonably be considered to know (due to the fact they were previously informed of because that node has itself advertised knowledge of the hashes through NewBlockHashes) is considered Bad Form, and may reduce the reputation of the sending node.

2 Answers 2

2

What are the exact rules applied by Geth, Parity, and/or other clients to determine a peer's reputation?

The exact answer to this is the source code for each client. To answer this question I've only looked at Geth's source, I can't speak to what Parity does.

In particular, is being honest sufficient to get a good or even optimal reputation or is usefulness required for this as well?

After looking at Geth it appears that usefulness is the only thing which is considered. Remote nodes which Geth has been able to quickly receive data from are preferentially used for future requests.

Under what condition do peers disconnect?

If you search eth/downloader/downloader.go for "errBadPeer" you'll get some examples. In general it disconnects when the remote peer gives Geth responses which are invalid such as returning one block header when Geth asked for a different block header.

Is reputation remembered beyond the lifetime of a connection and used for peer selection (for instance in order to prevent immediate reconnects by bad peers)?

As far as I can tell (after like 10 minutes of reading code) Geth has no memory of bad peers. It simply disconnects and forgets all about the peer.


A search in geth's source for "reputation" only turns up matches in eth/downloader/peer.go.

It has some blocks which look like this:

// HeaderIdlePeers retrieves a flat list of all the currently header-idle peers
// within the active peer set, ordered by their reputation.
func (ps *peerSet) HeaderIdlePeers() ([]*peerConnection, int) {
    idle := func(p *peerConnection) bool {
        return atomic.LoadInt32(&p.headerIdle) == 0
    }
    throughput := func(p *peerConnection) float64 {
        p.lock.RLock()
        defer p.lock.RUnlock()
        return p.headerThroughput
    }
    return ps.idlePeers(62, 64, idle, throughput)
}

The blocks all call idlePeers:

// idlePeers retrieves a flat list of all currently idle peers satisfying the
// protocol version constraints, using the provided function to check idleness.
// The resulting set of peers are sorted by their measure throughput.
func (ps *peerSet) idlePeers(minProtocol, maxProtocol int, idleCheck func(*peerConnection) bool, throughput func(*peerConnection) float64) ([]*peerConnection, int) {
    ps.lock.RLock()
    defer ps.lock.RUnlock()


    idle, total := make([]*peerConnection, 0, len(ps.peers)), 0
    for _, p := range ps.peers {
        if p.version >= minProtocol && p.version <= maxProtocol {
            if idleCheck(p) {
                idle = append(idle, p)
            }
            total++
        }
    }
    for i := 0; i < len(idle); i++ {
        for j := i + 1; j < len(idle); j++ {
            if throughput(idle[i]) < throughput(idle[j]) {
                idle[i], idle[j] = idle[j], idle[i]
            }
        }
    }
    return idle, total
}

idlePeers, does not seem to track reputation. Instead it orders peers based on their measured throughput. Amusingly enough, it does so with a bubblesort :)

1

The Ethereum blockchain utilizes a Proof-of-Work (PoW) variant in an implementation called Ethash. PoW does not involve reputation. The reputation you're reading about likely refers to "off-chain" reputation e.g. public scorn or 2nd layer reputation engines that track and award/punish based on some calculated measure of miner reputation (e.g. bonding curves and TCRs).

Many attempts are being made by researchers both at Ethereum and at other organizations to move away from PoW-esque consensus mechanisms - that empower those with greater computational power thus encouraging hardware centralization/collusion - toward those that value "honest actors" e.g. Proof-of-Stake (PoS), where miners stake their money and lose it if they're "wrong" about state changes, basically. You can read more about all that jazz here and here.

In regards to your last question:

Is reputation remembered beyond the lifetime of a connection and used for peer selection (for instance in order to prevent immediate reconnects by bad peers)?

This alludes to one of the many reasons why a meritocratic, reputation-based consensus algorithm is so difficult to conjure. It has to do with Sybil Resistance. If I was a miner with awful reputation within a PoW blockchain that cared about reputation, then I could always start mining from a new address i.e. a new identity, hence why PoW implementations don't care about any form of reputation. PoS is better at this because you can only have so much money no matter how many "identities" you own (though PoS certainly has other flaws).

1
  • This doesn't answer the question. I'm asking about reputation at the p2p networking layer, not the consensus layer.
    – Jannik
    Mar 11, 2019 at 8:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.