private ConsensusMessage CreateConfMessage(BoolSet values) { var message = new ConsensusMessage { Conf = new ConfMessage { Agreement = _broadcastId.Agreement, Epoch = _broadcastId.Epoch, Values = { values.Values() } } }; return(message); }
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(); }
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; }
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(); } }
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; } } }