Пример #1
0
 private ConsensusMessage CreateEchoMessage(ValMessage valMessage)
 {
     return(new ConsensusMessage
     {
         EchoMessage = new ECHOMessage
         {
             SenderId = _broadcastId.SenderId,
             MerkleTreeRoot = valMessage.MerkleTreeRoot,
             Data = valMessage.Data,
             MerkleProof = { valMessage.MerkleProof }
         }
     });
 }
Пример #2
0
        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);
        }
Пример #3
0
        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");
            }
        }