Skip to content

Instantly share code, notes, and snippets.

@sapristi
Last active June 4, 2023 10:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sapristi/3cc76ab36a1efdc9a9f6fc2cc492011b to your computer and use it in GitHub Desktop.
Save sapristi/3cc76ab36a1efdc9a9f6fc2cc492011b to your computer and use it in GitHub Desktop.
Locutus

Locutus

How to detect malfunctioning / byzantine nodes?

Situation

  • Nodes W, X, Y and Z hold the state of contract c
  • Node X has W and Y as peers
  • A is any node
  • We measure performance of X
graph TB
  classDef BYZ fill:#FF0060
  classDef A fill:#159895
  subgraph holders_of_contract_c
     W
     X:::BYZ
     Y
     Z
     W -.- X -.- Y
  end
  A:::A

Assumptions

  1. A node doesn’t know the original emitter of a request → is this true ? what’s the request protocol ?

  2. Each message is

    • signed by the emitting node
    • contains timestamp of emission
    • contains the request

    This allows to make nodes be held accountable for what they send.

  3. Gossip (between holders of a contract that are also peers) follows a different protocol that regular requests for a state contract. Note sure this needs to be true. But it’s safer to assume it is, since it is a less strong hypothesis.

  4. By sending a similar request to different peers, a node can reach different holders of a given contract.

Proposal

Node benchmark

A node can perform a “benchmark” of the holders of a given contract:

  • it sends request for state of contract c to multiple nodes / peers of his, and hopes to reach multiple different nodes holding c ’s state
graph TB
  classDef BYZ fill:#FF0060
  classDef A fill:#159895
  subgraph holders_of_contract_c
     W
     X:::BYZ
     Y
     Z
     W -.- X -.- Y
  end
  A:::A
  A1[_]
  A2[_]
  A3[_]
  A -->|c?| A1 --> W
  A -->|c?| A2 --> X
  A -->|c?| A3 --> Z

linkStyle 3,5,7 stroke-dasharray: 8

So now X possesses the state of contract c as given by W, X and Y. By repeating this regularly, it can have statistical data showing whether a node is

  • malfunctioning (i.e. late on having updates)
  • lying about the contracts state

Since all messages are signed, the answers that A gathered can be used as proof that e.g. node X is malfunctioning.

Details

  1. Why do we need an external node to perform the benchmark:

    • X cannot directly ask W for it’s state, because W knows that X also holds c ’s state (and thus could be truthful, because it knows it’s being watched). X could however ask other peers, and hope that the request ends up on other holders of the contract.
  2. A node cannot fake the request associated with the answers it sends (one could imagine a node would do this to avoid proof buildup).

    • doing this would be a straightforward reason to be banned by individual nodes (indeed creating shareable proof would be difficult, but no-one would listen to it in the first place anyway).
  3. Should a node be aware that proof is being accumulated against it ?

    • If one cannot differentiate a lying node from a node having technical issues, then yes. This could also be used as a mechanism to detect potential network issues ?
  4. Using gossips as additional proof

    • Once a node is identified as potential lier, one could imagine using gossip logs to show that a node knew the real state of a contract, but decided to send a wrong answer to a request.

Preventing sybil attacks

Make sure a node cannot impact where it will end up in the ring space. The best way to do this would be that the node position is somehow tied to the token emitted by the reputation-emiting oracle.

If an attacker cannot impact where it’s node will be placed, it will be very expensive to gather enough resources to overcome the consensus of truthful nodes on a given contract.

One could however imagine a sybil attack where coordinated byzantine nodes would pre-emptively decide to hold the state of a given contract. Even though they would have much less chance to be contacted for this contract’s state than the “correct” ones, with enough nodes, the attack could be successful.

Timing problems

A big issue with the proposed solution is when the watched contract often changes in state. In this case, the different probe request would return different values, and this would be normal.

  1. This is not likely to cause harm (i.e. wrongly flagging nodes as lying) because there would be no consensus.
  2. A state that changes often means it is also used often - i.e. many users. We can thus imagine that users could combine efforts, allowing more fine-grained probes
  3. There is a special case, for which we could ask for a less strong guarantee. Let's take the live chat usecase:
    • The state is supposed to be an ever-increasing list of messages, where old messages cannot be modified.
    • In this condition, we could judge whether two states are "compatible", i.e it is possible that one state precedes the other one. This would for example prevent a node from inserting messages in the list afterwards
    • This way, without needing very close probe messages, we could still detect some forms of lying / errors.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment