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

Gossipsub: message filtering #122

Closed
arnetheduck opened this issue Feb 18, 2019 · 10 comments
Closed

Gossipsub: message filtering #122

arnetheduck opened this issue Feb 18, 2019 · 10 comments
Assignees
Milestone

Comments

@arnetheduck
Copy link
Member

With regards to ethereum/eth2.0-specs#593

When messages are received on the network, we should not propagate them unless they're "good" (to be defined).

libp2p allows blacklisting peers by peer id (which is secured by the above feature, https://github.com/libp2p/go-libp2p-pubsub/blob/master/blacklist_test.go#L38-L64).

There also exists a validation api (https://github.com/libp2p/go-libp2p-pubsub/blob/bfd65a2f6b810c5b4ad2cfe6bb9cc792fd7a0171/floodsub_test.go#L360) to filter messages by content - it is making its way into the daemon api as well: libp2p/go-libp2p-daemon#71

How do we make use of this information? should it affect peer scoring?

@cheatfate
Copy link
Contributor

cheatfate commented Feb 19, 2019

With some help from libp2p we can make validators anonymous in the libp2p network:
https://hackmd.io/Mn7pPTtVTfWrg0RRhKBpNA#

@zah
Copy link
Contributor

zah commented Oct 24, 2019

One previously raised concern of the "validation API" is that it's not defined to be async. This won't be a problem for us if we can use the following alternative approach:

  1. Always block the incoming messages for re-transmission by simple doing return false.
  2. Add them to a queue for validation.
  3. Once validated, gossip them normally as new messages.

This approach also gives us the opportunity to look at the pool of collected messages before deciding what should be re-transmitted. Similar prioritisation strategy is proposed for attestation aggregation here: https://notes.ethereum.org/9Ijj2RkuRiqQYB9NOfY_9Q

@zah zah modified the milestones: ETH1-bridged Nimbus-only Testnet, ETH1-bridged multi-client testnet Oct 24, 2019
@tersec
Copy link
Contributor

tersec commented Dec 6, 2019

To suggest the capabilities of what sort of filtering is implementable: https://github.com/ethereum/eth2.0-specs/blob/v0.9.2/specs/networking/p2p-interface.md#topics-and-messages requires the following filtering:

  • Probably should live in a layer closer to libp2p: Each gossipsub message has a maximum size of GOSSIP_MAX_SIZE. Clients MUST reject (fail validation) messages that are over this size limit. Likewise, clients MUST NOT emit or propagate messages larger than this limit.

  • Clients MUST reject (fail validation) messages containing an incorrect type, or invalid payload. (check matching beacon_block topic with BeaconBlock message type, beacon_aggregate_and_proof topic with AggregateAndProof message type, etc, and reject anything not from that fixed list.

  • For each topic/message type pair, there are specific verification checks, e.g., beacon_block - This topic is used solely for propagating new beacon blocks to all nodes on the networks. Blocks are sent in their entirety. Clients MUST validate the block proposer signature before forwarding it across the network. The general theme is that one validates the relevant messages via process_voluntary_exit(), process_proposer_slashing(), or process_attester_slashing() as appropriate before accepting or retransmitting.

@mratsim mratsim modified the milestones: ETH1-bridged multi-client testnet, Feb 2020 Feb 5, 2020
@dryajov
Copy link
Member

dryajov commented Feb 5, 2020

Pubsub validators were added in libp2p in vacp2p/nim-libp2p#58. This should be available to use as a filtering mechanism now.

@tersec
Copy link
Contributor

tersec commented Feb 18, 2020

In terms of nim-libp2p APIs, remaining are a couple of things, validation-wise:

For our current purposes, there is no need to address messages based on source peer, and it seems likely we might even override the message from to obfuscate the peer. By overriding the default message-id to use content-addressing we can filter unnecessary duplicates before hitting the application layer.

such that The message-id of a gossipsub message MUST be: message-id: base64(SHA256(message.data)). It's not clear this information should available at all to the Ethereum 2 networking layer as such, or compliant with the libp2p specification.

@dryajov
Copy link
Member

dryajov commented Feb 18, 2020

The message-id of a gossipsub message MUST be: message-id: base64(SHA256(message.data)).

This is currently impossible to do in some (most?) implementations as the gossipsub RPC message isn't exposed to the application, consequently the neither the message-id nor the from fields are accessible. Currently, the nim-libp2p doesn't expose this functionality either.

Given that Eth2 networking spec mandates this for all clients, we should propose this changes to be included in the gossipsub spec.

@tersec
Copy link
Contributor

tersec commented Feb 18, 2020

Other already-done aspects, in terms of what nim-beacon-chain implements (it largely doesn't interact with these messages) from https://github.com/ethereum/eth2.0-specs/blob/v0.10.1/specs/phase0/p2p-interface.md#global-topics and which aren't necessary for attestation aggregation include:

Additional global topics are used to propagate lower frequency validator messages. Their TopicNames are:

  • voluntary_exit - This topic is used solely for propagating signed voluntary validator exits to proposers on the network. Signed voluntary exits are sent in their entirety. Clients who receive a signed voluntary exit on this topic MUST validate the conditions within process_voluntary_exit before forwarding it across the network.
  • proposer_slashing - This topic is used solely for propagating proposer slashings to proposers on the network. Proposer slashings are sent in their entirety. Clients who receive a proposer slashing on this topic MUST validate the conditions within process_proposer_slashing before forwarding it across the network.
  • attester_slashing - This topic is used solely for propagating attester slashings to proposers on the network. Attester slashings are sent in their entirety. Clients who receive an attester slashing on this topic MUST validate the conditions within process_attester_slashing before forwarding it across the network.

Also already done:

beacon_block - This topic is used solely for propagating new signed beacon blocks to all nodes on the networks. Signed blocks are sent in their entirety. The following validations MUST pass before forwarding the signed_beacon_block on the network

The proposer signature, signed_beacon_block.signature is valid.
The block is not from a future slot (with a MAXIMUM_GOSSIP_CLOCK_DISPARITY allowance) -- i.e. validate that signed_beacon_block.message.slot <= current_slot (a client MAY queue future blocks for processing at the appropriate slot).

The necessary code already exists (all those process_* functions already work and are tested by the EF test vectors).

@tersec
Copy link
Contributor

tersec commented Mar 5, 2020

Items in #781 related to content-hashing in for message-ID and for max gossip message size are out of scope of this issue for March purposes, leaving only the nim-beacon-chain internal ones.

@tersec
Copy link
Contributor

tersec commented Mar 17, 2020

For beacon_block (https://github.com/ethereum/eth2.0-specs/blob/v0.11.0/specs/phase0/p2p-interface.md#global-topics):

  • The block is not from a future slot (with a MAXIMUM_GOSSIP_CLOCK_DISPARITY allowance) -- i.e. validate that signed_beacon_block.message.slot <= current_slot (a client MAY queue future blocks for processing at the appropriate slot).

  • The block is from a slot greater than the latest finalized slot (with a MAXIMUM_GOSSIP_CLOCK_DISPARITY allowance) -- i.e. validate that signed_beacon_block.message.slot > compute_start_slot_at_epoch(state.finalized_checkpoint.epoch) (a client MAY choose to validate and store such blocks for additional purposes -- e.g. slashing detection, archive nodes, etc).

  • The block is the first block with valid signature received for the proposer for the slot, signed_beacon_block.message.slot.

  • The proposer signature, signed_beacon_block.signature, is valid.

For attestations (https://github.com/ethereum/eth2.0-specs/blob/v0.11.0/specs/phase0/p2p-interface.md#attestation-subnets):

  • The attestation's committee index (attestation.data.index) is for the correct subnet.

  • attestation.data.slot is within the last ATTESTATION_PROPAGATION_SLOT_RANGE slots (within a MAXIMUM_GOSSIP_CLOCK_DISPARITY allowance) -- i.e. attestation.data.slot + ATTESTATION_PROPAGATION_SLOT_RANGE >= current_slot >= attestation.data.slot (a client MAY queue future attestations for processing at the appropriate slot).

  • The attestation is unaggregated -- that is, it has exactly one participating validator (len([bit for bit in attestation.aggregation_bits if bit == 0b1]) == 1).

  • The attestation is the first valid attestation received for the participating validator for the slot, attestation.data.slot.

  • The block being voted for (attestation.data.beacon_block_root) passes validation.

  • The signature of attestation is valid.

@tersec
Copy link
Contributor

tersec commented Mar 31, 2020

#812 implements this.

@tersec tersec closed this as completed Mar 31, 2020
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

No branches or pull requests

6 participants