Beispiel #1
0
        public BeneficiarySession(
            VaspContractInfo beneficiaryVaspContractInfo,
            VaspInformation beneficiaryVasp,
            string sessionId,
            string counterpartyTopic,
            string counterPartyPubSigningKey,
            string sharedKey,
            string privateSigningKey,
            IWhisperRpc whisperRpc,
            IVaspMessageHandler vaspMessageHandler,
            ITransportClient transportClient,
            ISignService signService)
            : base(
                beneficiaryVaspContractInfo,
                beneficiaryVasp,
                counterPartyPubSigningKey,
                sharedKey,
                privateSigningKey,
                whisperRpc,
                transportClient,
                signService)
        {
            this.SessionId           = sessionId;
            this.CounterPartyTopic   = counterpartyTopic;
            this._vaspMessageHandler = vaspMessageHandler;

            _messageHandlerResolverBuilder.AddHandler(typeof(TransferRequestMessage), new TransferRequestMessageHandler(
                                                          async(message, cancellationToken) =>
            {
                await _vaspMessageHandler.TransferRequestHandlerAsync(message, this);
            }));

            _messageHandlerResolverBuilder.AddHandler(typeof(TransferDispatchMessage), new TransferDispatchMessageHandler(
                                                          async(message, cancellationToken) =>
            {
                await _vaspMessageHandler.TransferDispatchHandlerAsync(message, this);
            }));

            _messageHandlerResolverBuilder.AddHandler(typeof(TerminationMessage),
                                                      new TerminationMessageHandler(async(message, token) =>
            {
                _hasReceivedTerminationMessage = true;
                await TerminateAsync(message.GetMessageCode());
            }));
        }
        /// <summary>
        /// Run listener which would process incoming messages.
        /// </summary>
        /// <param name="messageHandler">Handler which authorizes originator's Vasp and processes Transfer Request and Transfer Dispatch Messages</param>
        public void RunListener(IVaspMessageHandler messageHandler)
        {
            lock (_lock)
            {
                if (!_hasStartedListening)
                {
                    _hasStartedListening = true;
                    var token       = _cancellationTokenSource.Token;
                    var taskFactory = new TaskFactory(_cancellationTokenSource.Token);

                    this._listener = taskFactory.StartNew(async(_) =>
                    {
                        var privateKeyId     = await _whisperRpc.RegisterKeyPairAsync(this._handshakeKey.PrivateKey);
                        string messageFilter =
                            await _whisperRpc.CreateMessageFilterAsync(topicHex: _vaspContractInfo.VaspCode.Code,
                                                                       privateKeyId);

                        do
                        {
                            var sessionRequestMessages = await _transportClient.GetSessionMessagesAsync(messageFilter);

                            if (sessionRequestMessages != null &&
                                sessionRequestMessages.Count != 0)
                            {
                                foreach (var message in sessionRequestMessages)
                                {
                                    var sessionRequestMessage = message.Message as SessionRequestMessage;

                                    if (sessionRequestMessage == null)
                                    {
                                        continue;
                                    }

                                    var isAuthorized =
                                        await messageHandler.AuthorizeSessionRequestAsync(sessionRequestMessage.VASP);

                                    if (!isAuthorized)
                                    {
                                        continue;
                                    }

                                    var originatorVaspContractInfo =
                                        await _ethereumRpc.GetVaspContractInfoAync(sessionRequestMessage.VASP
                                                                                   .VaspIdentity);

                                    if (!_signService.VerifySign(message.Payload, message.Signature,
                                                                 originatorVaspContractInfo.SigningKey))
                                    {
                                        continue;
                                    }

                                    var sharedSecret =
                                        this._handshakeKey.GenerateSharedSecretHex(sessionRequestMessage.HandShake
                                                                                   .EcdhPubKey);

                                    var session = new BeneficiarySession(
                                        originatorVaspContractInfo,
                                        this.VaspInfo,
                                        sessionRequestMessage.Message.SessionId,
                                        sessionRequestMessage.HandShake.TopicA,
                                        originatorVaspContractInfo.SigningKey,
                                        sharedSecret,
                                        this._signatureKey,
                                        this._whisperRpc,
                                        messageHandler,
                                        _transportClient,
                                        _signService);

                                    this.NotifySessionCreated(session);
                                    session.OnSessionTermination += this.ProcessSessionTermination;
                                    if (_beneficiarySessionsDict.TryAdd(session.SessionId, session))
                                    {
                                        await session.StartAsync();
                                    }
                                    else
                                    {
                                        await session.TerminateAsync(TerminationMessage.TerminationMessageCode
                                                                     .SessionClosedTransferDeclinedByBeneficiaryVasp);
                                    }
                                }

                                continue;
                            }

                            await Task.Delay(5000, token);
                        } while (!token.IsCancellationRequested);
                    }, token, TaskCreationOptions.LongRunning);
                }
                else
                {
                    throw new Exception("You can start observation only once.");
                }
            }
        }