spacemeshos / go-spacemesh

Go Implementation of the Spacemesh protocol full node. 💾⏰💪
https://spacemesh.io
MIT License
747 stars 211 forks source link

generate NIPoST malfeasance proof #4251

Open countvonzero opened 1 year ago

countvonzero commented 1 year ago

Description

if one of the k2 indices fails to verify, we should generate a malfeasance proof.

for atx/ballot/hare msgs, the malfeasance proof are two messages signed by the same miner but have different message hash. for NiPost, it's just the (ATX, bad_index) pair. the idea is that if miner signs an ATX that contains an index that doesn't meet the difficulty threshold, this miner is considered malicious.

the malfeasance proof is verified by verifying the bad index indeed didn't meet the difficulty threshold.

@poszu please fill in more details as you see fit. thanks

dshulyak commented 1 year ago

can you share the reason for doing this change? simple syntactic validation is enough to prevent someone from sharing invalid proofs. it seems to me that it creeps in because of plans for "distributed" verification..

for example doing this change naively allows to spam network with malfeasance proofs, so you atleast shouldn't do it for initial atx

dshulyak commented 1 year ago

from Iddo

this malfeasance object won't be stored long-term, just instead of propagating the bad ATX the honest nodes will propagate this malfeasance object (that's almost the same size as the bad ATX), and blacklist any peer that sent the bad ATX not wrapped inside this malfeasance object. We will need to verify k2pow too, to make it demanding to mount the DoS attack (the attacker will need to compute a demanding k2pow and get his IP blacklisted for each bad ATX that he propagates). We really need distributed verification, so it's worth it to make k2pow more demanding, and this way we can also achieve tighter PoST k1,k2 params.

dshulyak commented 1 year ago

more from Iddo

The attacker can avoid getting his IP blacklisted by only broadcasting the malfeasance object (ATX, bad_index) in the first place. This way the attacker pretends to be an honest node that helps the network by propagating this dummy ATX that he created. But the difficulty of k2pow will be high, so the attacker will still need a valid k2pow for each dummy ATX that he propogates.If we later implement the network optimized variant, each node will first send to its direct neighbors the short malfeasance object that consists of just (hash_of_ATX, index_of_bad_label), and the neighbor will ask for the ATX if he doesn't have the preimage yet. So if the attacker created a dummy ATX and sends only (hash_of_ATX, index_of_bad_label), then the honest neighbor will ask the attacker for the preimage, and if the attacker doesn't reply quickly with the preimage (that contains the valid k2pow) then his IP will be blacklisted.Either way (with or without the network optimized implementation), if k2pow is difficult enough then DoS'ing our gossip network can be done in cheaper ways compared to exploiting this malfeasance object.As mentioned, the DoS damage using this dummy malfeasance object is "incomparable" (that is, worse in some respects and better in some other respects) to the DoS damage of just creating dummy ATXs that are demanding to verify (requiring dozens of scrypt invocations). It's incomparable hecause malfeasance object is easier to verify but needs to propagate during the epoch.

dshulyak commented 1 year ago

i understood that malfeasence should be created only if post proof passed k2pow, but one of the indexes was wrong. so if someone will want to spam network with invalid atxs, they will have to spend time computing k2pow.

@poszu how long k2pow takes?

poszu commented 1 year ago

@poszu how long k2pow takes?

It depends on:

With the latest mainnet params from the notebook it took me around 17ms on i7-12700 with a single core