private ConsensusMessage CreateEchoMessage(ValMessage valMessage) { return(new ConsensusMessage { EchoMessage = new ECHOMessage { SenderId = _broadcastId.SenderId, MerkleTreeRoot = valMessage.MerkleTreeRoot, Data = valMessage.Data, MerkleProof = { valMessage.MerkleProof } } }); }
private ValMessage[] ConstructValMessages(IReadOnlyList <byte> input) { var shards = ErasureCodingShards(input, N, 2 * F); var merkleTree = ConstructMerkleTree(shards); var result = new ValMessage[N]; for (var i = 0; i < N; ++i) { result[i] = new ValMessage { SenderId = _broadcastId.SenderId, MerkleTreeRoot = merkleTree[1], MerkleProof = { MerkleTreeBranch(merkleTree, i) }, Data = ByteString.CopyFrom(shards[i]), }; } return(result); }
private void HandleValMessage(ValMessage val, int validator) { var validatorPubKey = Wallet.EcdsaPublicKeySet[validator].ToHex(); if (_sentValMessage[validator]) { Logger.LogWarning($"{Id}: validator {validator} ({validatorPubKey}) tried to send VAL message twice"); return; } Logger.LogTrace( $"Protocol {Id} got VAL message from {validator} ({validatorPubKey}), sending ECHO" ); _sentValMessage[validator] = true; // Before sending echo, we can check if validator == val.SenderId, means if the val message is from the correct validator // Because one validator cannot produce val message of another validator, it can only send echo. // If we don't check this condition, there could be potential issue, for example, a malicious validator (id = x) sends a // val message that has random shards but correct MerkleProof and uses val.SenderId = y (another validator), and sends to // validator with id = z. It will be constructed as echo message and sent to everyone by validator, id = z, this echo will // pass the CheckEchoMessage(). Now every honest validator will think that val message of validator of id = y is confirmed // by echo message from validator of id = z. When the correct val message of id = y will come to id = z, he will send echo // again but others will not accept it, because id = z already sent echo for id = y, (but it was from malicious id = x), // because the correct echo for each pair is received only once. if (validator == val.SenderId) { Broadcaster.Broadcast(CreateEchoMessage(val)); } else { var pubKey = Broadcaster.GetPublicKeyById(validator) !.ToHex(); Logger.LogWarning( $"Faulty behaviour: val message with sender id: {val.SenderId} came from validator: " + $"{validator} ({pubKey}), which should not happen. Val message for {val.SenderId} should come " + $"from {val.SenderId}. Not sending echo message for this val message"); } }