Пример #1
0
        private ConsensusMessage CreateConfMessage(BoolSet values)
        {
            var message = new ConsensusMessage
            {
                Conf = new ConfMessage
                {
                    Agreement = _broadcastId.Agreement,
                    Epoch     = _broadcastId.Epoch,
                    Values    = { values.Values() }
                }
            };

            return(message);
        }
Пример #2
0
        private void HandleBValMessage(int sender, BValMessage bval)
        {
            if (bval.Epoch != _broadcastId.Epoch || bval.Agreement != _broadcastId.Agreement)
            {
                throw new ArgumentException("era, agreement or epoch of message mismatched");
            }

            var b = bval.Value ? 1 : 0;

            if (_receivedValues[sender].Contains(b == 1))
            {
                Logger.LogTrace($"{_broadcastId}: double receive message {bval} from {sender}");
                return;
            }

            _receivedValues[sender].Add(b == 1);
            ++_receivedCount[b];

            if (!_wasBvalBroadcasted[b] && _receivedCount[b] >= F + 1)
            {
                BroadcastBVal(bval.Value);
            }

            if (_receivedCount[b] < 2 * F + 1)
            {
                return;
            }
            if (_binValues.Contains(b == 1))
            {
                return;
            }

            _binValues = _binValues.Add(b == 1);
            if (_binValues.Count() == 1)
            {
                Broadcaster.Broadcast(CreateAuxMessage(b));
            }

            RevisitAuxMessages();
            RevisitConfMessages();
        }
Пример #3
0
        public BinaryBroadcast(
            BinaryBroadcastId broadcastId, IPublicConsensusKeySet wallet, IConsensusBroadcaster broadcaster)
            : base(wallet, broadcastId, broadcaster)
        {
            _broadcastId = broadcastId;
            _requested   = ResultStatus.NotRequested;

            _binValues         = new BoolSet();
            _receivedValues    = new BoolSet[N];
            _playerSentAux     = new bool[N];
            _validatorSentConf = new bool[N];
            for (var i = 0; i < N; ++i)
            {
                _receivedValues[i] = new BoolSet();
            }
            _receivedCount      = new int[2];
            _receivedAux        = new int[2];
            _wasBvalBroadcasted = new bool[2];
            _confReceived       = new List <BoolSet>();
            _result             = null;
            _confSent           = false;
        }
Пример #4
0
        public void RunBinaryAgreementRandom(
            int n, int f, DeliveryServiceMode mode,
            int muteCnt = 0, double repeatProbability = .0
            )
        {
            SetUpAllHonest(n, f);
            _deliveryService.RepeatProbability = repeatProbability;
            _deliveryService.Mode = mode;
            while (_deliveryService.MutedPlayers.Count < muteCnt)
            {
                _deliveryService.MutePlayer(_rnd.Next(0, n));
            }

            var used = new BoolSet();

            for (var i = 0; i < n; ++i)
            {
                var cur = _rnd.Next() % 2 == 1;
                used = used.Add(cur);
                _broadcasters[i].InternalRequest(new ProtocolRequest <BinaryAgreementId, bool>(
                                                     _resultInterceptors[i].Id, (_broadcasts[i].Id as BinaryAgreementId) !, cur
                                                     ));
            }

            for (var i = 0; i < n; ++i)
            {
                if (_deliveryService.MutedPlayers.Contains(i))
                {
                    continue;
                }
                _broadcasts[i].WaitResult();
            }

            _deliveryService.WaitFinish();

            for (var i = 0; i < n; ++i)
            {
                if (_deliveryService.MutedPlayers.Contains(i))
                {
                    continue;
                }

                Assert.AreEqual(
                    _resultInterceptors[i].ResultSet, 1,
                    $"protocol has {i} emitted result not once but {_resultInterceptors[i].ResultSet}"
                    );
            }

            bool?res = null;

            for (var i = 0; i < n; ++i)
            {
                if (_deliveryService.MutedPlayers.Contains(i))
                {
                    continue;
                }
                var ans = _resultInterceptors[i].Result;
                res ??= ans;
                Assert.AreEqual(res, _resultInterceptors[i].Result);
            }

            Assert.IsNotNull(res);
            Assert.True(used.Contains(res !.Value));

            for (var i = 0; i < n; ++i)
            {
                _broadcasts[i].Terminate();
                _broadcasts[i].WaitFinish();
            }
        }
Пример #5
0
        private void TryProgressEpoch()
        {
            CheckResult();
            while (_result == null || !_wasRepeat)
            {
                if (_currentEpoch % 2 == 0)
                {
                    // epoch mod 2 = 0 -> we have not yet initiated BB
                    if (_currentEpoch != 0 && !_coins.ContainsKey(_currentEpoch - 1))
                    {
                        /*    Logger.LogTrace(
                         *      $"{_agreementId}: can't progress epoch, blocked, coin (Ep={_currentEpoch - 1}) not present"); */
                        return; // we cannot progress since coin is not tossed and estimate is not correct
                    }

                    /*    Logger.LogTrace(
                     *      $"Epoch progressed, coin (Ep={_currentEpoch - 1}) is present " +
                     *      $"with value {_currentEpoch > 0 && _coins[_currentEpoch - 1]}"
                     *  ); */
                    // we have right to calculate new estimate and proceed
                    if (_currentEpoch != 0)
                    {
                        var s = _coins[_currentEpoch - 1];
                        _estimate = _currentValues.Values().First();

                        if (_currentValues.Count() == 1 && _result == null)
                        {
                            if (_estimate == s)
                            {
                                // we are winners!
                                _resultEpoch = _currentEpoch;
                                _result      = _estimate;
                                CheckResult();
                                Logger.LogTrace($"{_agreementId}: result = {_result} achieved at Ep={_currentEpoch}");
                            }
                        }
                        else if (_result == s)
                        {
                            if (_currentEpoch > _resultEpoch)
                            {
                                Logger.LogTrace(
                                    $"{_agreementId}: value repeated at Ep={_currentEpoch}, result is already obtained: {_result}. Terminating protocol"
                                    );
                                _wasRepeat = true;
                                Terminate();
                            }
                        }
                        else
                        {
                            _estimate = s;
                        }
                    }

                    if (_result != null)
                    {
                        _estimate = _result.Value;
                    }

                    // here we start new BB assuming that current estimate is correct
                    var broadcastId = new BinaryBroadcastId(_agreementId.Era, _agreementId.AssociatedValidatorId,
                                                            _currentEpoch);
                    Broadcaster.InternalRequest(
                        new ProtocolRequest <BinaryBroadcastId, bool>(Id, broadcastId, _estimate)
                        );
                    _currentEpoch += 1;
                }
                else
                {
                    // epoch mod 2 = 1 -> we have not yet tossed coin
                    if (!_binaryBroadcastsResults.ContainsKey(_currentEpoch - 1))
                    {
                        /*    Logger.LogTrace(
                         *      $"{_agreementId}: can't progress epoch, blocked, BB (Ep={_currentEpoch - 1}) not present"
                         *  ); */
                        return; // we cannot progress since BB is not completed
                    }

                    //    Logger.LogTrace($"{_agreementId}: epoch progressed, BB (Ep={_currentEpoch - 1}) is present");

                    _currentValues = _binaryBroadcastsResults[_currentEpoch - 1];
                    var coinId = new CoinId(_agreementId.Era, _agreementId.AssociatedValidatorId, _currentEpoch);
                    if ((_currentEpoch / 2) % 3 == 2)
                    {
                        Broadcaster.InternalRequest(new ProtocolRequest <CoinId, object?>(Id, coinId, null));
                    }
                    else
                    {
                        _coins[_currentEpoch] = ((_currentEpoch / 2) % 3) != 0;
                    }

                    _currentEpoch += 1;
                }
            }
        }