Open stanbar opened 1 year ago
I'm not an expert on Byzantine nodes. The Wesh protocol is designed for delay-tolerant networks which only need eventual consistency among nodes. But they will reach consensus on the order of messages when all of them have arrived. But I don't know enough to suggest an approach for your use case.
Without implementing consensus directly in the Wesh protocol, you could use it as the lower messaging layer of some consensus system. Does that work?
they will reach consensus on the order of messages when all of them have arrived.
The problem is when a (malicious) node sends two messages with the same lamport's clock time. How can other nodes determine which one is valid and which one is not? Consensus is needed to agree on one of many conflicting versions.
I did some research and found a paper Making CRDTs Byzantine Fault Tolerant. The author promises:
This paper shows how to adapt existing non-Byzantine CRDT algorithms and make them Byzantine fault-tolerant. The proposed scheme can tolerate any number of Byzantine nodes (making it immune to Sybil attacks), guarantees Strong Eventual Consistency, and requires only modest changes to existing CRDT algorithms.
Here is a discussion on Hacker News about making CRDT byzantine fault tolerant.
Building a consensus mechanism on top of Wesh would be the best option. However, I'm not sure how to do it using Wesh. Your tutorials don't cover sending messages. I'm sure you are working on it, but could you please sketch how would implementing consensus protocol on top of Wesh look like? It would save me a lot of time 🙏
Since you use orbit-db underneath I also asked them for more information https://github.com/orbitdb/orbit-db/issues/1073
The Lamport clock uses a counter and the public key of the sender. A malicious user can send a message with the same Lamport clock (public key) as another group member, but the message signature will fail and will not become part of the message log, because the malicious user doesn't have the corresponding private key. (I'm pretty sure about this, but I could verify with our cryptographers.) The signature failure will prevent the problem you mentioned, right?
The problem is a bit different.
AFAIK the structure of messages in Wesh is like this:
{
payload: "A",
lamportClock: {
time: 1,
id: "0x123zxcv..."
},
signature: Ed25519(privkey, this.payload, this.lamportClock)
}
I'm ignoring the symmetric ratchet protocol as it doesn't change anything.
The problem is that a (malicious) user can create two conflicting messages:
const voteForA = {
payload: "A",
lamportClock: {
time: 1,
id: "0x123zxcv..."
},
signature: Ed25519(privkey, this.payload, this.lamportClock)
}
// and
const voteForB = {
payload: "B",
lamportClock: {
time: 1,
id: "0x123zxcv..."
},
signature: Ed25519(privkey, this.payload, this.lamportClock)
}
They are both equally valid.
Then the user broadcasts voteForA
to half of the network and voteForB
to the other half. Now the problem is, how the whole network can agree on one message. Nodes can not accept both because they are using the same time: 1
.
I see. Thanks for the clarification. I thought it was one malicious user trying to displace another user's message, but you are talking about one malicious user abusing the protocol with two conflicting messages. I have to ask about whether the Wesh protocol has a consideration for this.
Hi @stanbar. I did a quick read of the paper Making CRDTs Byzantine Fault Tolerant. One of its recommendations is to use the hash of an entry. Go-orbitDB is based on go-ipfs-log. It does use the entry hash in case two Lamport clocks are the same. So, there should not be the ability to replace one entry by another with the same Lamport clock. I know this doesn't fully implement the recommendations, but it is at least something. See the code: https://github.com/berty/go-ipfs-log/blob/master/entry/sorting/sorting.go#L66
@stanbar I'm in a similar boat as you for an MVP. Check this out: https://github.com/jackyzha0/bft-json-crdt
GitHub🏰 the first JSON-like Byzantine Fault Tolerant CRDT - GitHub - jackyzha0/bft-json-crdt: 🏰 the first JSON-like Byzantine Fault Tolerant CRDT
We are looking at working with some blockchain/smart contract projects but no details yet. We will keep this issue open and update when we know more.
@bitnom any update on that? How is your MVP going? Did you figure out how to do it?
The blockchain project is moving along, but we haven't gotten to the part where we will use Wesh for off-grid communication. Be aware that the project is not to implement a blockchain on top of Wesh, but to use Wesh for some of the operations in the existing blockchain system which can be done off-grid. For example, to access a device offline to sign a transaction. Or to update a message list (with Wesh) which will later be synced with the blockchain (not using Wesh).
Asking a question, not reporting a bug
Is there an existing issue for this?
Question
Hello, I'm building a p2p voting system and found Weshnet to ideally match my network assumptions. However, in our voting protocol, we have to assume that some nodes are malicious and want to manipulate the voting results. As a result, we need some byzantine fault-tolerant consensus mechanisms (ideally something like blockchain).
You mentioned why you don't need Blockchain for Berty app. But for the voting protocol, it's essential to determine the order of the messages, AFAIK Conflict-Free Replicated Data (https://berty.tech/docs/protocol/#conflict-free-replicated-data-type) won't help with byzantine nodes.
We need to achieve a consensus on the order of messages over participants of a group. Something like PBFT/Tendermint/Stellar Consensus Protocol (FBA) would work best. Can you suggest me some approach? Or maybe someone else tried to do that?
Context
The context has been described in the field above.