public async Task ChangeAddressAsync(INdmPeer peer, Address address) { if (peer.ProviderAddress == address) { return; } if (peer.ProviderAddress == null) { throw new InvalidOperationException($"While changing {nameof(INdmPeer.ProviderAddress)} to {address} found that the previous address has been null."); } Address previousAddress = peer.ProviderAddress; if (_logger.IsInfo) { _logger.Info($"Changing provider address: '{previousAddress}' -> '{address}' for peer: '{peer.NodeId}'."); } _providersWithCommonAddress.TryRemove(peer.ProviderAddress, out _); peer.ChangeProviderAddress(address); AddProviderNodes(peer); await _consumerNotifier.SendProviderAddressChangedAsync(address, previousAddress); if (_logger.IsInfo) { _logger.Info($"Changed provider address: '{previousAddress}' -> '{address}'."); } }
public void UpdateFaucet(INdmPeer peer) { _faucetPeer = peer; if (_logger.IsInfo) { _logger.Info($"Updated NDM faucet peer: {peer.NodeId}"); } }
public void AddDiscovered(DataAsset[] dataAssets, INdmPeer peer) { for (var i = 0; i < dataAssets.Length; i++) { var dataAsset = dataAssets[i]; _discoveredDataAssets.TryAdd(dataAsset.Id, dataAsset); } }
private void AddProviderNodes(INdmPeer peer) { var nodes = _providersWithCommonAddress.AddOrUpdate(peer.ProviderAddress, _ => new ConcurrentDictionary <PublicKey, string>(), (_, n) => n); nodes.TryAdd(peer.NodeId, string.Empty); if (_logger.IsInfo) { _logger.Info($"Added provider peer: '{peer.NodeId}' for address: '{peer.ProviderAddress}', nodes: {nodes.Count}."); } }
public async Task Can_handle_request_session_finish_even_when_peer_is_missing() { ConsumerSession consumerSession = new ConsumerSession(_session1Id, _deposit1Id, _asset1Id, _consumerAddress, _consumerNodeId, TestItem.AddressD, _providerNodeId, SessionState.Started, 1, 2, 4); INdmPeer peer = Substitute.For <INdmPeer>(); peer.ProviderAddress.Returns(TestItem.AddressD); await _sessionService.StartSessionAsync(consumerSession, peer); await _sessionService.SendFinishSessionAsync(_deposit1Id); _ndmPeer.DidNotReceive().SendFinishSession(_deposit1Id); }
public void Setup() { _dataAssetService = Substitute.For <IDataAssetService>(); _depositProvider = Substitute.For <IDepositProvider>(); _providerService = Substitute.For <IProviderService>(); _sessionService = Substitute.For <ISessionService>(); _wallet = Substitute.For <IWallet>(); _consumerNotifier = Substitute.For <IConsumerNotifier>(); _sessionRepository = Substitute.For <IConsumerSessionRepository>(); _providerPeer = Substitute.For <INdmPeer>(); _dataStreamService = new DataStreamService(_dataAssetService, _depositProvider, _providerService, _sessionService, _wallet, _consumerNotifier, _sessionRepository, LimboLogs.Instance); }
public async Task Cannot_start_session_for_an_unknown_provider() { ConsumerSession consumerSession = new ConsumerSession(_session1Id, _deposit1Id, _asset1Id, _consumerAddress, _consumerNodeId, _providerAddress, _providerNodeId, SessionState.Started, 1, 2, 4); INdmPeer mismatchedPeer = Substitute.For <INdmPeer>(); mismatchedPeer.ProviderAddress.Returns(TestItem.AddressD); mismatchedPeer.NodeId.Returns(TestItem.PublicKeyD); await _sessionService.StartSessionAsync(consumerSession, mismatchedPeer); var result = _sessionService.GetActive(_missingDepositId); result.Should().BeNull(); }
public async Task FinishSessionsAsync(INdmPeer provider, bool removePeer = true) { if (_logger.IsInfo) { _logger.Info($"Finishing {_sessions.Count} session(s) with provider: '{provider.ProviderAddress}'."); } if (removePeer) { _providerService.Remove(provider.NodeId); } if (provider.ProviderAddress is null) { if (_logger.IsWarn) { _logger.Warn($"Provider node: '{provider.NodeId}' has no address assigned."); } return; } var timestamp = _timestamper.EpochSeconds; foreach (var(_, session) in _sessions) { if (!provider.ProviderAddress.Equals(session.ProviderAddress)) { if (_logger.IsInfo) { _logger.Info($"Provider: '{provider.ProviderAddress}' address is invalid."); } continue; } var depositId = session.DepositId; if (_logger.IsInfo) { _logger.Info($"Finishing a session: '{session.Id}' for deposit: '{depositId}'."); } _sessions.TryRemove(session.DepositId, out _); session.Finish(SessionState.ProviderDisconnected, timestamp); await _sessionRepository.UpdateAsync(session); await _consumerNotifier.SendSessionFinishedAsync(session.DepositId, session.Id); if (_logger.IsInfo) { _logger.Info($"Finished a session: '{session.Id}' for deposit: '{depositId}', provider: '{provider.ProviderAddress}', state: '{session.State}', timestamp: {timestamp}."); } } }
private void AddProviderNodes(INdmPeer peer) { if (peer.ProviderAddress == null) { throw new InvalidOperationException("Trying to add a provider node without a provider address known."); } ConcurrentDictionary <PublicKey, string> nodes = _providersWithCommonAddress.AddOrUpdate(peer.ProviderAddress, _ => new ConcurrentDictionary <PublicKey, string>(), (_, n) => n); nodes.TryAdd(peer.NodeId, string.Empty); if (_logger.IsInfo) { _logger.Info($"Added provider peer: '{peer.NodeId}' for address: '{peer.ProviderAddress}', nodes: {nodes.Count}."); } }
public async Task Will_not_finish_sessions_from_other_providers() { ConsumerSession consumerSession = new ConsumerSession(_session1Id, _deposit1Id, _asset1Id, _consumerAddress, _consumerNodeId, _providerAddress, _providerNodeId, SessionState.Started, 1, 2, 4); await _sessionService.StartSessionAsync(consumerSession, _ndmPeer); INdmPeer otherPeer = Substitute.For <INdmPeer>(); otherPeer.ProviderAddress.Returns(TestItem.AddressD); otherPeer.NodeId.Returns(TestItem.PublicKeyD); await _sessionService.FinishSessionsAsync(otherPeer, true); var result = _sessionService.GetActive(_deposit1Id); result.Should().NotBeNull(); _providerService.GetPeer(_ndmPeer.ProviderAddress).Should().NotBeNull(); }
public void Setup() { IConsumerNotifier notifier = new ConsumerNotifier(Substitute.For <INdmNotifier>()); DepositsInMemoryDb db = new DepositsInMemoryDb(); IProviderRepository providerRepository = new ProviderInMemoryRepository(db); DataAssetProvider provider = new DataAssetProvider(_providerAddress, "provider"); DataAssetService dataAssetService = new DataAssetService(providerRepository, notifier, LimboLogs.Instance); _asset1 = new DataAsset(_asset1Id, "name", "desc", 1, DataAssetUnitType.Unit, 1000, 10000, new DataAssetRules(new DataAssetRule(1), new DataAssetRule(100)), provider, state: DataAssetState.Published); dataAssetService.AddDiscovered(_asset1, _ndmPeer); _deposit1 = new Deposit(_deposit1Id, 1, 2, 3); _details1 = new DepositDetails(_deposit1, _asset1, Address.Zero, new byte[0], 1, new TransactionInfo[0], 1); _asset2 = new DataAsset(_asset2Id, "name", "desc", 1, DataAssetUnitType.Time, 1000, 10000, new DataAssetRules(new DataAssetRule(1)), provider, state: DataAssetState.Published); dataAssetService.AddDiscovered(_asset2, _ndmPeer); _deposit2 = new Deposit(_deposit2Id, 1, 2, 3); _details2 = new DepositDetails(_deposit2, _asset2, Address.Zero, new byte[0], 1, new TransactionInfo[0], 2); _closed = new DataAsset(_closedId, "name", "desc", 1, DataAssetUnitType.Unit, 1000, 10000, new DataAssetRules(new DataAssetRule(1)), provider, state: DataAssetState.Closed); dataAssetService.AddDiscovered(_closed, _ndmPeer); _depositForClosed = new Deposit(_depositForClosedId, 1, 2, 3); _depositForClosedDetails = new DepositDetails(_depositForClosed, _closed, Address.Zero, new byte[0], 1, new TransactionInfo[0]); _missingAsset = new DataAsset(_missingAssetId, "name", "desc", 1, DataAssetUnitType.Unit, 1000, 10000, new DataAssetRules(new DataAssetRule(1)), provider, state: DataAssetState.Published); _depositForMissing = new Deposit(_depositForMissingId, 1, 2, 3); _depositForMissingDetails = new DepositDetails(_depositForMissing, _missingAsset, Address.Zero, new byte[0], 1, new TransactionInfo[0]); IDepositProvider depositProvider = Substitute.For <IDepositProvider>(); depositProvider.GetAsync(_deposit1Id).Returns(_details1); depositProvider.GetAsync(_deposit2Id).Returns(_details2); depositProvider.GetAsync(_depositForMissingId).Returns(_depositForMissingDetails); depositProvider.GetAsync(_depositForClosedId).Returns(_depositForClosedDetails); _ndmPeer = Substitute.For <INdmPeer>(); _ndmPeer.ProviderAddress.Returns(_providerAddress); _ndmPeer.NodeId.Returns(_providerNodeId); _providerService = new ProviderService(providerRepository, notifier, LimboLogs.Instance); _providerService.Add(_ndmPeer); _sessionRepository = new ConsumerSessionInMemoryRepository(); _sessionService = new SessionService(_providerService, depositProvider, dataAssetService, _sessionRepository, Timestamper.Default, notifier, LimboLogs.Instance); }
public void Setup() { DataAssetProvider provider = new DataAssetProvider(_providerAddress, "provider"); _asset = new DataAsset(Keccak.Compute("1"), "name", "desc", 1, DataAssetUnitType.Unit, 1000, 10000, new DataAssetRules(new DataAssetRule(1)), provider, state: DataAssetState.Published); _closedAsset = new DataAsset(Keccak.Compute("2"), "name", "desc", 1, DataAssetUnitType.Unit, 1000, 10000, new DataAssetRules(new DataAssetRule(1)), provider, state: DataAssetState.Closed); _assetUnderMaintenance = new DataAsset(Keccak.Compute("3"), "name", "desc", 1, DataAssetUnitType.Unit, 1000, 10000, new DataAssetRules(new DataAssetRule(1)), provider, state: DataAssetState.UnderMaintenance); _withKyc = new DataAsset(Keccak.Compute("4"), "name", "desc", 1, DataAssetUnitType.Unit, 1000, 10000, new DataAssetRules(new DataAssetRule(1)), provider, state: DataAssetState.Published, kycRequired: true); _deposit = new Deposit(Keccak.Zero, 1, 2, 3); _details = new DepositDetails(_deposit, _asset, Address.Zero, new byte[0], 1, new TransactionInfo[0]); INdmBlockchainBridge blockchainBridge = BlockchainBridgeBuilder.BuildABridge(); _wallet = new DevWallet(new WalletConfig(), LimboLogs.Instance); DepositService depositService = new DepositService(blockchainBridge, new AbiEncoder(), _wallet, Address.Zero); IConsumerSessionRepository sessionRepository = new ConsumerSessionInMemoryRepository(); DepositUnitsCalculator unitsCalculator = new DepositUnitsCalculator(sessionRepository, Timestamper.Default); DepositsInMemoryDb depositsInMemoryDb = new DepositsInMemoryDb(); depositsInMemoryDb.Add(_details); IProviderRepository providerRepository = new ProviderInMemoryRepository(depositsInMemoryDb); IConsumerNotifier notifier = new ConsumerNotifier(Substitute.For <INdmNotifier>()); DataAssetService dataAssetService = new DataAssetService(providerRepository, notifier, LimboLogs.Instance); IDepositUnitsCalculator depositUnitsCalculator = Substitute.For <IDepositUnitsCalculator>(); INdmPeer peer = Substitute.For <INdmPeer>(); peer.NodeId.Returns(TestItem.PublicKeyB); peer.ProviderAddress.Returns(_providerAddress); dataAssetService.AddDiscovered(_asset, peer); dataAssetService.AddDiscovered(_closedAsset, peer); dataAssetService.AddDiscovered(_assetUnderMaintenance, peer); dataAssetService.AddDiscovered(_withKyc, peer); _kycVerifier = Substitute.For <IKycVerifier>(); ProviderService providerService = new ProviderService(providerRepository, notifier, LimboLogs.Instance); providerService.Add(peer); _depositManager = new DepositManager(depositService, unitsCalculator, dataAssetService, _kycVerifier, providerService, new AbiEncoder(), new CryptoRandom(), _wallet, Substitute.For <IGasPriceService>(), new DepositDetailsInMemoryRepository(depositsInMemoryDb, depositUnitsCalculator), Timestamper.Default, LimboLogs.Instance, 6, false); }
public void Setup() { INdmPeer peer = Substitute.For <INdmPeer>(); peer.ProviderAddress.Returns(_providerAddress); _providerId = TestItem.PublicKeyB; peer.NodeId.Returns(_providerId); DataAssetProvider provider = new DataAssetProvider(_providerAddress, "name"); DataAsset newPendingAsset = new DataAsset(_newPendingAssetId, "name", "desc", 1, DataAssetUnitType.Unit, 1000, 10000, new DataAssetRules(new DataAssetRule(1), null), provider); DataAsset pendingAsset = new DataAsset(_pendingAssetId, "name", "desc", 1, DataAssetUnitType.Unit, 1000, 10000, new DataAssetRules(new DataAssetRule(1), null), provider); DataAsset rejectedAsset = new DataAsset(_rejectedAssetId, "name", "desc", 1, DataAssetUnitType.Unit, 1000, 10000, new DataAssetRules(new DataAssetRule(1), null), provider); DataAsset confirmedAsset = new DataAsset(_confirmedAssetId, "name", "desc", 1, DataAssetUnitType.Unit, 1000, 10000, new DataAssetRules(new DataAssetRule(1), null), provider); DepositsInMemoryDb db = new DepositsInMemoryDb(); ProviderInMemoryRepository providerRepository = new ProviderInMemoryRepository(db); _cdaRepo = new ConsumerDepositApprovalInMemoryRepository(); _ndmNotifier = Substitute.For <INdmNotifier>(); ConsumerNotifier notifier = new ConsumerNotifier(_ndmNotifier); DataAssetService dataAssetService = new DataAssetService(providerRepository, notifier, LimboLogs.Instance); dataAssetService.AddDiscovered(newPendingAsset, peer); dataAssetService.AddDiscovered(pendingAsset, peer); dataAssetService.AddDiscovered(rejectedAsset, peer); dataAssetService.AddDiscovered(confirmedAsset, peer); _providerService = new ProviderService(providerRepository, notifier, LimboLogs.Instance); _providerService.Add(peer); _service = new DepositApprovalService(dataAssetService, _providerService, _cdaRepo, Timestamper.Default, notifier, LimboLogs.Instance); _confirmedApproval = new DepositApproval(Keccak.Compute(Rlp.Encode(Rlp.Encode(_confirmedAssetId), Rlp.Encode(_consumerAddress)).Bytes), _confirmedAssetId, "asset", "kyc", _consumerAddress, _providerAddress, 1, DepositApprovalState.Confirmed); _pendingApproval = new DepositApproval(Keccak.Compute(Rlp.Encode(Rlp.Encode(_pendingAssetId), Rlp.Encode(_consumerAddress)).Bytes), _pendingAssetId, "asset", "kyc", _consumerAddress, _providerAddress, 1, DepositApprovalState.Pending); _rejectedApproval = new DepositApproval(Keccak.Compute(Rlp.Encode(Rlp.Encode(_rejectedAssetId), Rlp.Encode(_consumerAddress)).Bytes), _rejectedAssetId, "asset", "kyc", _consumerAddress, _providerAddress, 1, DepositApprovalState.Rejected); _cdaRepo.AddAsync(_confirmedApproval); _cdaRepo.AddAsync(_pendingApproval); _cdaRepo.AddAsync(_rejectedApproval); }
public async Task ChangeAddressAsync(INdmPeer peer, Address address) { if (peer.ProviderAddress == address) { return; } var previousAddress = peer.ProviderAddress; if (_logger.IsInfo) { _logger.Info($"Changing provider address: '{previousAddress}' -> '{address}' for peer: '{peer.NodeId}'."); } _providersWithCommonAddress.TryRemove(peer.ProviderAddress, out _); peer.ChangeProviderAddress(address); AddProviderNodes(peer); await _consumerNotifier.SendProviderAddressChangedAsync(address, previousAddress); if (_logger.IsInfo) { _logger.Info($"Changed provider address: '{previousAddress}' -> '{address}'."); } }
public async Task FinishSessionAsync(Session session, INdmPeer provider, bool removePeer = true) { if (removePeer) { _providerService.Remove(provider.NodeId); } if (provider.ProviderAddress is null) { if (_logger.IsWarn) { _logger.Warn($"Provider node: '{provider.NodeId}' has no address assigned."); } return; } var depositId = session.DepositId; var consumerSession = GetActive(depositId); if (consumerSession is null) { return; } _sessions.TryRemove(session.DepositId, out _); var timestamp = session.FinishTimestamp; consumerSession.Finish(session.State, timestamp); await _sessionRepository.UpdateAsync(consumerSession); await _consumerNotifier.SendSessionFinishedAsync(session.DepositId, session.Id); if (_logger.IsInfo) { _logger.Info($"Finished a session: '{session.Id}' for deposit: '{depositId}', provider: '{provider.ProviderAddress}', state: '{session.State}', timestamp: {timestamp}."); } }
public void Add(INdmPeer peer) { _providers.TryAdd(peer.NodeId, peer); AddProviderNodes(peer); }
public async Task StartSessionAsync(Session session, INdmPeer provider) { // var providerPeer = _providerService.GetPeer(provider.ProviderAddress); // if (!_providers.TryGetValue(provider.NodeId, out var providerPeer)) // { // if (_logger.IsWarn) _logger.Warn($"Cannot start the session: '{session.Id}', provider: '{provider.NodeId}' was not found."); // // return; // } var deposit = await _depositProvider.GetAsync(session.DepositId); if (deposit is null) { if (_logger.IsWarn) { _logger.Warn($"Cannot start the session: '{session.Id}', deposit: '{session.DepositId}' was not found."); } return; } var dataAssetId = deposit.DataAsset.Id; var dataAsset = _dataAssetService.GetDiscovered(dataAssetId); if (dataAsset is null) { if (_logger.IsWarn) { _logger.Warn($"Available data asset: '{dataAssetId}' was not found."); } return; } if (!_dataAssetService.IsAvailable(dataAsset)) { if (_logger.IsWarn) { _logger.Warn($"Data asset: '{dataAssetId}' is unavailable, state: {dataAsset.State}."); } return; } if (!provider.ProviderAddress.Equals(deposit.DataAsset.Provider.Address)) { if (_logger.IsWarn) { _logger.Warn($"Cannot start the session: '{session.Id}' for deposit: '{session.DepositId}', provider address (peer): '{provider.ProviderAddress}' doesn't equal the address from data asset: '{deposit.DataAsset.Provider.Address}'."); } return; } var sessions = await _sessionRepository.BrowseAsync(new GetConsumerSessions { DepositId = session.DepositId, Results = int.MaxValue }); var consumedUnits = sessions.Items.Any() ? (uint)sessions.Items.Sum(s => s.ConsumedUnits) : 0; if (_logger.IsInfo) { _logger.Info($"Starting the session: '{session.Id}' for deposit: '{session.DepositId}'. Settings consumed units - provider: {session.StartUnitsFromProvider}, consumer: {consumedUnits}."); } var consumerSession = ConsumerSession.From(session); consumerSession.Start(session.StartTimestamp); var previousSession = await _sessionRepository.GetPreviousAsync(consumerSession); var upfrontUnits = (uint)(deposit.DataAsset.Rules.UpfrontPayment?.Value ?? 0); if (upfrontUnits > 0 && previousSession is null) { consumerSession.AddUnpaidUnits(upfrontUnits); if (_logger.IsInfo) { _logger.Info($"Unpaid units: {upfrontUnits} for session: '{session.Id}' based on upfront payment."); } } var unpaidUnits = previousSession?.UnpaidUnits ?? 0; if (unpaidUnits > 0 && !(previousSession is null)) { consumerSession.AddUnpaidUnits(unpaidUnits); if (_logger.IsInfo) { _logger.Info($"Unpaid units: {unpaidUnits} for session: '{session.Id}' from previous session: '{previousSession.Id}'."); } } if (deposit.DataAsset.UnitType == DataAssetUnitType.Time) { var unpaidTimeUnits = (uint)consumerSession.StartTimestamp - deposit.ConfirmationTimestamp; consumerSession.AddUnpaidUnits(unpaidTimeUnits); if (_logger.IsInfo) { _logger.Info($"Unpaid units: '{unpaidTimeUnits}' for deposit: '{session.DepositId}' based on time."); } } SetActiveSession(consumerSession); await _sessionRepository.AddAsync(consumerSession); await _consumerNotifier.SendSessionStartedAsync(session.DepositId, session.Id); if (_logger.IsInfo) { _logger.Info($"Started a session with id: '{session.Id}' for deposit: '{session.DepositId}', address: '{deposit.Consumer}'."); } }
public void AddDiscoveredDataAssets(DataAsset[] dataAssets, INdmPeer peer) => _dataAssetService.AddDiscovered(dataAssets, peer);
public void AddDiscovered(DataAsset dataAsset, INdmPeer peer) { _discoveredDataAssets.TryAdd(dataAsset.Id, dataAsset); }
public Task FinishSessionsAsync(INdmPeer provider, bool removePeer = true) => _sessionService.FinishSessionsAsync(provider, removePeer);
public void AddDiscoveredDataAsset(DataAsset dataAsset, INdmPeer peer) => _dataAssetService.AddDiscovered(dataAsset, peer);
public Task StartSessionAsync(Session session, INdmPeer provider) => _sessionService.StartSessionAsync(session, provider);
public void AddProviderPeer(INdmPeer peer) => _providerService.Add(peer);
public Task ChangeProviderAddressAsync(INdmPeer peer, Address address) => _providerService.ChangeAddressAsync(peer, address);
public void Setup() { _logManager = NullLogManager.Instance; _faucetPeer = Substitute.For <INdmPeer>(); _ethRequestService = new EthRequestService(FaucetHost, _logManager); }
public async Task StartSessionAsync(Session session, INdmPeer provider) { DepositDetails?deposit = await _depositProvider.GetAsync(session.DepositId); if (deposit is null) { if (_logger.IsWarn) { _logger.Warn($"Cannot start the session: '{session.Id}', deposit: '{session.DepositId}' was not found."); } return; } if (session.StartTimestamp < deposit.ConfirmationTimestamp) { if (_logger.IsWarn) { _logger.Warn($"Cannot start the session: '{session.Id}', session timestamp {session.StartTimestamp} is before deposit confirmation timestamp {deposit.ConfirmationTimestamp}."); } return; } Keccak dataAssetId = deposit.DataAsset.Id; if (dataAssetId != session.DataAssetId) { if (_logger.IsWarn) { _logger.Warn($"Inconsistent data - data asset ID on deposit is '{dataAssetId}' while on session is '{session.DataAssetId}'."); } return; } DataAsset?dataAsset = _dataAssetService.GetDiscovered(dataAssetId); if (dataAsset is null) { if (_logger.IsWarn) { _logger.Warn($"Available data asset: '{dataAssetId}' was not found."); } return; } if (!_dataAssetService.IsAvailable(dataAsset)) { if (_logger.IsWarn) { _logger.Warn($"Data asset: '{dataAssetId}' is unavailable, state: {dataAsset.State}."); } return; } if (session.ProviderAddress == null) { if (_logger.IsWarn) { _logger.Warn($"Session: '{session.Id}' for '{session.DepositId}' cannot be started because of the unknown provider address."); } return; } if (!provider.ProviderAddress !.Equals(deposit.DataAsset.Provider.Address)) { if (_logger.IsWarn) { _logger.Warn($"Cannot start the session: '{session.Id}' for deposit: '{session.DepositId}', provider address (peer): '{provider.ProviderAddress}' doesn't equal the address from data asset: '{deposit.DataAsset.Provider.Address}'."); } return; } PagedResult <ConsumerSession> sessions = await _sessionRepository.BrowseAsync(new GetConsumerSessions { DepositId = session.DepositId, Results = int.MaxValue }); uint consumedUnits = sessions.Items.Any() ? (uint)sessions.Items.Sum(s => s.ConsumedUnits) : 0; if (_logger.IsInfo) { _logger.Info($"Starting the session: '{session.Id}' for deposit: '{session.DepositId}'. Settings consumed units - provider: {session.StartUnitsFromProvider}, consumer: {consumedUnits}."); } ConsumerSession consumerSession = ConsumerSession.From(session); consumerSession.Start(session.StartTimestamp); ConsumerSession?previousSession = await _sessionRepository.GetPreviousAsync(consumerSession); uint upfrontUnits = (uint)(deposit.DataAsset.Rules.UpfrontPayment?.Value ?? 0); if (upfrontUnits > 0 && previousSession is null) { consumerSession.AddUnpaidUnits(upfrontUnits); if (_logger.IsInfo) { _logger.Info($"Unpaid units: {upfrontUnits} for session: '{session.Id}' based on upfront payment."); } } uint unpaidUnits = previousSession?.UnpaidUnits ?? 0; if (unpaidUnits > 0 && !(previousSession is null)) { consumerSession.AddUnpaidUnits(unpaidUnits); if (_logger.IsInfo) { _logger.Info($"Unpaid units: {unpaidUnits} for session: '{session.Id}' from previous session: '{previousSession.Id}'."); } } if (deposit.DataAsset.UnitType == DataAssetUnitType.Time) { uint unpaidTimeUnits = (uint)consumerSession.StartTimestamp - deposit.ConfirmationTimestamp; consumerSession.AddUnpaidUnits(unpaidTimeUnits); if (_logger.IsInfo) { _logger.Info($"Unpaid units: '{unpaidTimeUnits}' for deposit: '{session.DepositId}' based on time."); } } SetActiveSession(consumerSession); await _sessionRepository.AddAsync(consumerSession); await _consumerNotifier.SendSessionStartedAsync(session.DepositId, session.Id); if (_logger.IsInfo) { _logger.Info($"Started a session with id: '{session.Id}' for deposit: '{session.DepositId}', address: '{deposit.Consumer}'."); } }