public void TestPopCallBackHandlerForSpecificMessage_RemovesAllOtherHandlersForThisCorrelationId() { var logger = new Mock<ILogger>(); var callbackHandlerStack = new CallbackHandlerStack(new ExpirableItemCollection<CorrelationId>(logger.Object)); var correlationId = new CorrelationId(Guid.NewGuid().ToByteArray()); var promise = new Promise(); var messageHandlerIdentifiers = new[] { new MessageIdentifier(Message.CurrentVersion, SimpleMessage.MessageIdentity), new MessageIdentifier(Message.CurrentVersion, ExceptionMessage.MessageIdentity) }; callbackHandlerStack.Push(correlationId, promise, messageHandlerIdentifiers); var handler = callbackHandlerStack.Pop(new CallbackHandlerKey { Identity = SimpleMessage.MessageIdentity, Version = Message.CurrentVersion, Correlation = correlationId.Value }); Assert.IsNotNull(handler); handler = callbackHandlerStack.Pop(new CallbackHandlerKey { Identity = ExceptionMessage.MessageIdentity, Version = Message.CurrentVersion, Correlation = correlationId.Value }); Assert.IsNull(handler); }
private ApplicationError OnException(Exception ex, CorrelationId correlationId) { if (ex == null) throw new ArgumentNullException(nameof(ex)); var unwrapped = UnwrapTargetInvocation(ex); var reflectionTypeLoadException = unwrapped as ReflectionTypeLoadException; if (reflectionTypeLoadException?.LoaderExceptions != null) { foreach (var loadException in reflectionTypeLoadException.LoaderExceptions) { _logger.Error("Could not load types", loadException); } } var dbEntityValidationException = unwrapped as DbEntityValidationException; _logger.Error("Request throws exception", unwrapped); if (dbEntityValidationException?.EntityValidationErrors != null) { foreach (var dbEntityValidationResult in dbEntityValidationException.EntityValidationErrors) { foreach (var dbValidationError in dbEntityValidationResult.ValidationErrors) { _logger.Error( $"Entity {dbEntityValidationResult.Entry.Entity.GetType()} error property {dbValidationError.PropertyName}. Error message {dbValidationError.ErrorMessage}"); } } } var res = new ApplicationError { Exception = unwrapped, CorrelationId = correlationId, Code = GetStatusCodeByException(unwrapped), Message = unwrapped.Message, IncludeErrorDetails = _includeErrorDetailsResolver.IncludeErrorDetails ?? false }; return res; }
public async Task InvokeTest() { var mr = new MockRepository(MockBehavior.Strict); var next = mr.Create<OwinMiddleware>(MockBehavior.Strict, (OwinMiddleware)null); var ctx = mr.Create<IOwinContext>(); var cidStore = mr.Create<ICorrelationIdStore>(); var response = mr.Create<IOwinResponse>(); var hDict = new HeaderDictionary(new Dictionary<string, string[]>()); var correlationId = new CorrelationId(); next.Setup(x => x.Invoke(ctx.Object)).Returns(Task.CompletedTask).Verifiable(); ctx.SetupGet(x => x.Response).Returns(response.Object).Verifiable(); response.SetupGet(x => x.Headers).Returns(hDict).Verifiable(); cidStore.Setup(x => x.Read()).Returns(correlationId).Verifiable(); Assert.AreEqual(0, hDict.Count); var midleware = new SetCorrelationIdHeaderMiddleware(next.Object, cidStore.Object); await midleware.Invoke(ctx.Object); Assert.AreEqual(1, hDict.Count); var actual = hDict["X-CORRELATIONID"]; Assert.AreEqual(correlationId.ToString(), actual); mr.VerifyAll(); }
public void ToDatedStringTest() { var id = Guid.NewGuid(); var dt = DateTime.UtcNow; var ds = new CorrelationId(id).ToDatedString(); Assert.AreEqual($"{id}__{dt.ToString("yyyyMMdd_hhmmss")}", ds); }
private void RemoveExpiredCallback(CorrelationId correlationId) { IDictionary<MessageIdentifier, IPromise> value; if (handlers.TryRemove(correlationId, out value)) { ((Promise)value.Values.First()).SetExpired(); } }
public void Push(CorrelationId correlation, IPromise promise, IEnumerable<MessageIdentifier> messageIdentifiers) { IDictionary<MessageIdentifier, IPromise> messageHandlers; if (handlers.TryGetValue(correlation, out messageHandlers)) { throw new DuplicatedKeyException($"Duplicated key: Correlation[{correlation.Value.GetString()}]"); } var delayedItem = expirationQueue.Delay(correlation, promise.ExpireAfter); ((Promise)promise).SetExpiration(delayedItem); handlers[correlation] = messageIdentifiers.ToDictionary(mp => mp, mp => promise); }
public void TestProvidedMethods() { var i1 = Guid.NewGuid(); var i2 = Guid.NewGuid(); var c1 = new CorrelationId(i1); var c2 = new CorrelationId(i2); Assert.AreEqual(i1.CompareTo(i2), c1.CompareTo(c2)); // Compare correlation id and correlation id Assert.AreEqual(i1.CompareTo(i2), c1.CompareTo(i2)); // Compare correlation id and Guid Assert.AreEqual(i1.CompareTo((object)i2), c1.CompareTo((object)c2)); // Compare correlation id and object cid Assert.AreEqual(i1.CompareTo((object)i2), c1.CompareTo((object)i2)); // Compare correlation id and object Guid Assert.IsTrue(c1.Equals(new CorrelationId(i1))); // Equals correlation id and correlation id Assert.IsFalse(c1.Equals(new CorrelationId(i2))); // Not equals correlation id and correlation id Assert.IsTrue(c1.Equals((object)new CorrelationId(i1))); // Equals correlation id and object correlation id Assert.IsFalse(c1.Equals((object)new CorrelationId(i2))); // Not equals correlation id and object correlation id Assert.IsTrue(c1.Equals(i1)); // Equals correlation id and Guid Assert.IsFalse(c1.Equals(i2)); // Not equals correlation id and Guid Assert.IsFalse(c1.Equals((object)i1)); // Not equals correlation id and object Guid Assert.IsFalse(c1.Equals((object)i2)); // Not equals correlation id and object Guid Assert.AreEqual(i1.GetHashCode(), c1.GetHashCode()); // GetHashCode Assert.AreNotEqual(i2.GetHashCode(), c1.GetHashCode()); Assert.AreEqual(c1.GetHashCode(), c1.GetHashCode()); Assert.AreNotEqual(c2.GetHashCode(), c1.GetHashCode()); CollectionAssert.AreEqual(i1.ToByteArray(), c1.ToByteArray()); // To byte array CollectionAssert.AreNotEqual(i2.ToByteArray(), c1.ToByteArray()); CollectionAssert.AreEqual(i2.ToByteArray(), c2.ToByteArray()); CollectionAssert.AreNotEqual(i1.ToByteArray(), c2.ToByteArray()); Assert.AreEqual(i1.ToString(), c1.ToString()); // To string Assert.AreNotEqual(i2.ToString(), c1.ToString()); Assert.AreEqual(i2.ToString(), c2.ToString()); Assert.AreNotEqual(i1.ToString(), c2.ToString()); Assert.AreEqual(i1.ToString("N"), c1.ToString("N")); // To string with format Assert.AreNotEqual(i2.ToString("N"), c1.ToString("N")); Assert.AreEqual(i2.ToString("N"), c2.ToString("N")); Assert.AreNotEqual(i1.ToString("N"), c2.ToString("N")); var c = CultureInfo.CurrentCulture; Assert.AreEqual(i1.ToString("D", c), c1.ToString("D", c)); // To string with format and provider Assert.AreNotEqual(i2.ToString("D", c), c1.ToString("D", c)); Assert.AreEqual(i2.ToString("D", c), c2.ToString("D", c)); Assert.AreNotEqual(i1.ToString("D", c), c2.ToString("D", c)); }
public void TestAddingHandlersForExistingCorrelation_ThrowsDuplicatedKeyException() { var logger = new Mock<ILogger>(); var callbackHandlerStack = new CallbackHandlerStack(new ExpirableItemCollection<CorrelationId>(logger.Object)); var correlationId = new CorrelationId(Guid.NewGuid().ToByteArray()); var promise = new Promise(); callbackHandlerStack.Push(correlationId, promise, Enumerable.Empty<MessageIdentifier>()); Assert.Throws<DuplicatedKeyException>(() => { callbackHandlerStack.Push(correlationId, promise, Enumerable.Empty<MessageIdentifier>()); }); }
public void InitializeAllTest() { Debug.WriteLine(Assembly.GetExecutingAssembly().Location); var manager = Manager(); _resolver.Setup(x => x.Resolve()).Returns(new[] { typeof(IItemWrapper<string>), typeof(IItemWrapper<Type>), typeof(IItemWrapper<CorrelationId>) }).Verifiable(); var stringMock = _factory.Create<IItemWrapper>(); var typeMock = _factory.Create<IItemWrapper>(); var corrIdMock = _factory.Create<IItemWrapper<CorrelationId>>(); _wrappersFactory.Setup(x => x.Get(typeof(IItemWrapper<string>))).Returns(stringMock.Object).Verifiable(); _wrappersFactory.Setup(x => x.Get(typeof(IItemWrapper<Type>))).Returns(typeMock.Object).Verifiable(); _wrappersFactory.Setup(x => x.Get(typeof(IItemWrapper<CorrelationId>))).Returns(corrIdMock.Object).Verifiable(); stringMock.Setup(x => x.Initialize()).Verifiable(); typeMock.Setup(x => x.Initialize()).Verifiable(); corrIdMock.Setup(x => x.Initialize()).Verifiable(); var correlationId = new CorrelationId(); corrIdMock.Setup(x => x.Current).Returns(correlationId).Verifiable(); _correlationIdStore.Setup(x => x.Save(correlationId)).Verifiable(); manager.InitializeAll(); }
public void returns_ids_from_headers() { _idsFromContext["requestId"].Value <string>().ShouldBe(RequestId.ToString()); _idsFromContext["correlationId"].Value <string>().ShouldBe(CorrelationId.ToString()); _idsFromContext["sessionId"].Value <string>().ShouldBe(SessionId.ToString()); }
internal bool TryReadSimpleType(out object result, out SerializationTokenType token) { token = ReadToken(); byte[] bytes; switch (token) { case SerializationTokenType.True: result = true; break; case SerializationTokenType.False: result = false; break; case SerializationTokenType.Null: result = null; break; case SerializationTokenType.Object: result = new object(); break; case SerializationTokenType.Int: result = ReadInt(); break; case SerializationTokenType.Uint: result = ReadUInt(); break; case SerializationTokenType.Short: result = ReadShort(); break; case SerializationTokenType.Ushort: result = ReadUShort(); break; case SerializationTokenType.Long: result = ReadLong(); break; case SerializationTokenType.Ulong: result = ReadULong(); break; case SerializationTokenType.Byte: result = ReadByte(); break; case SerializationTokenType.Sbyte: result = ReadSByte(); break; case SerializationTokenType.Float: result = ReadFloat(); break; case SerializationTokenType.Double: result = ReadDouble(); break; case SerializationTokenType.Decimal: result = ReadDecimal(); break; case SerializationTokenType.String: result = ReadString(); break; case SerializationTokenType.Character: result = ReadChar(); break; case SerializationTokenType.Guid: bytes = ReadBytes(16); result = new Guid(bytes); break; case SerializationTokenType.Date: result = DateTime.FromBinary(ReadLong()); break; case SerializationTokenType.TimeSpan: result = new TimeSpan(ReadLong()); break; case SerializationTokenType.GrainId: result = ReadGrainId(); break; case SerializationTokenType.ActivationId: result = ReadActivationId(); break; case SerializationTokenType.SiloAddress: result = ReadSiloAddress(); break; case SerializationTokenType.ActivationAddress: result = ReadActivationAddress(); break; case SerializationTokenType.IpAddress: result = ReadIPAddress(); break; case SerializationTokenType.IpEndPoint: result = ReadIPEndPoint(); break; case SerializationTokenType.CorrelationId: result = new CorrelationId(ReadBytes(CorrelationId.SIZE_BYTES)); break; default: result = null; return false; } return true; }
internal Channel(IExchange exchange, IExchangePool exchanges, TimeSpan timeout, Action <object?> cancellationCallback, CorrelationId id) { this.exchange = exchange; timeoutTokenSource = new CancellationTokenSource(timeout); cancellation = timeoutTokenSource.Token.Register(cancellationCallback, id); exchangeOwner = exchanges; }
public CashWithdrawn(CorrelationId correlationId, SourceId sourceId) : base(correlationId, sourceId) { }
public AccountUnblocked(CorrelationId correlationId, SourceId sourceId) : base(correlationId, sourceId) { }
public static CommittedEvent build_committed_event(VersionedEventSource versionedEventSource, IEvent @event, CommittedEventVersion version) { var metadata = new EventMetadata(EventId.New(), versionedEventSource, CorrelationId.New(), new Artifact(ArtifactId.New(), 1), DateTime.UtcNow, GetOriginalContext()); return(new CommittedEvent(version, metadata, @event)); }
public Entry(IContainSagaData sagaData, CorrelationId correlationId) { CorrelationId = correlationId; data = sagaData; }
public void returns_ids_from_context() { _ids["requestId"].Value <string>().ShouldBe(RequestId.ToString()); _ids["correlationId"].Value <string>().ShouldBe(CorrelationId.ToString()); _ids["sessionId"].Value <string>().ShouldBe("(Not available)"); }
/// <inheritdoc /> public ExecutionContext CreateFor(TenantId tenant, Version version, CorrelationId correlation, ActivitySpanId?spanId, Claims claims) => new(
public async Task <IActionResult> BeginOpenChannel( [ModelBinder(BinderType = typeof(TumblerParametersModelBinder))] ClassicTumblerParameters tumblerId, [FromBody] OpenChannelRequest request) { if (tumblerId == null) { throw new ArgumentNullException(nameof(tumblerId)); } var height = Services.BlockExplorerService.GetCurrentHeight(); if (Repository.IsUsed(request.CycleStart, request.Nonce)) { throw new ActionResultException(BadRequest("duplicate-query")); } var cycle = GetCycle(request.CycleStart); if (!cycle.IsInPhase(CyclePhase.TumblerChannelEstablishment, height)) { throw new ActionResultException(BadRequest("invalid-phase")); } var fee = Services.FeeService.GetFeeRate(); try { if (!Parameters.VoucherKey.PublicKey.Verify(request.Signature, NBitcoin.Utils.ToBytes((uint)request.CycleStart, true), request.Nonce)) { throw new ActionResultException(BadRequest("incorrect-voucher")); } if (!Repository.MarkUsedNonce(request.CycleStart, request.Nonce)) { throw new ActionResultException(BadRequest("duplicate-query")); } var escrowKey = new Key(); var escrow = new EscrowScriptPubKeyParameters(); escrow.LockTime = cycle.GetTumblerLockTime(); escrow.Receiver = request.EscrowKey; escrow.Initiator = escrowKey.PubKey; var channelId = new uint160(RandomUtils.GetBytes(20)); Logs.Tumbler.LogInformation($"Cycle {cycle.Start} Asked to open channel"); var txOut = new TxOut(Parameters.Denomination, escrow.ToScript().WitHash.ScriptPubKey.Hash); var unused = Services.WalletService.FundTransactionAsync(txOut, fee) .ContinueWith(async(Task <Transaction> task) => { try { var tx = await task.ConfigureAwait(false); var correlation = new CorrelationId(channelId); Tracker.TransactionCreated(cycle.Start, TransactionType.TumblerEscrow, tx.GetHash(), correlation); //Logging/Broadcast per funding TX one time if (Repository.MarkUsedNonce(cycle.Start, new uint160(tx.GetHash().ToBytes().Take(20).ToArray()))) { var bobCount = Parameters.CountEscrows(tx, Client.Identity.Bob); Logs.Tumbler.LogInformation($"Cycle {cycle.Start} channel created {tx.GetHash()} with {bobCount} users"); await Services.BroadcastService.BroadcastAsync(tx).ConfigureAwait(false); } await Services.BlockExplorerService.TrackAsync(txOut.ScriptPubKey).ConfigureAwait(false); Tracker.AddressCreated(cycle.Start, TransactionType.TumblerEscrow, txOut.ScriptPubKey, correlation); var coin = tx.Outputs.AsCoins().First(o => o.ScriptPubKey == txOut.ScriptPubKey && o.TxOut.Value == txOut.Value); var session = new PromiseServerSession(Parameters.CreatePromiseParamaters()); var redeem = await Services.WalletService.GenerateAddressAsync().ConfigureAwait(false); session.ConfigureEscrowedCoin(channelId, coin.ToScriptCoin(escrow.ToScript()), escrowKey, redeem.ScriptPubKey); var redeemTx = session.CreateRedeemTransaction(_Network, fee); Services.TrustedBroadcastService.Broadcast(cycle.Start, TransactionType.TumblerRedeem, correlation, redeemTx); Repository.Save(cycle.Start, session); Tracker.AddressCreated(cycle.Start, TransactionType.TumblerRedeem, redeem.ScriptPubKey, correlation); } catch (Exception ex) { Logs.Tumbler.LogCritical(new EventId(), ex, "Error during escrow transaction callback"); } }); return(new BitcoinSerializableResult(channelId.AsBitcoinSerializable())); } catch (NotEnoughFundsException ex) { Logs.Tumbler.LogInformation(ex.Message); throw new ActionResultException(BadRequest("tumbler-insufficient-funds")); } }
public void TestRefEquals() { var c = new CorrelationId(); Assert.IsTrue(c.Equals(c)); Assert.IsTrue(c.Equals((object)c)); Assert.IsFalse(c.Equals((object)null)); Assert.IsFalse(c.Equals((CorrelationId)null)); }
public WithdrawalFailed(CorrelationId correlationId, SourceId sourceId) : base(correlationId, sourceId) { }
public void Save(CorrelationId id) { _owinContextResolver.Current?.Set(CorrelationId, id); CallContext.LogicalSetData(CorrelationId, id); }
private IObserverDto <ProtocolMessage> GetFileFromDfsRequestMessage() { var getFileFromDfsRequestMessage = new GetFileFromDfsRequest { DfsHash = _hashProvider.ComputeUtf8MultiHash("test").ToBase32() }; var protocolMessage = getFileFromDfsRequestMessage .ToProtocolMessage(PeerIdHelper.GetPeerId("TestMan"), CorrelationId.GenerateCorrelationId()); return(new ObserverDto(Substitute.For <IChannelHandlerContext>(), protocolMessage)); }
/// <summary> /// Initializes a new instance of the <see cref="RequestCorrelationContext"/> class. /// </summary> /// <param name="correlationId">Request correlation ID.</param> /// <param name="originHeader">Header name containing correlation ID.</param> public RequestCorrelationContext(CorrelationId correlationId, string originHeader) : base(correlationId) { Header = originHeader ?? throw new ArgumentNullException(nameof(originHeader)); }
public WireFundTransferred(CorrelationId correlationId, SourceId sourceId) : base(correlationId, sourceId) { }
public bool Equals([AllowNull] ExtendedProperty other) { return(other != null && CorrelationId.Equals(other.CorrelationId)); }
public ChequeDeposited(CorrelationId correlationId, SourceId sourceId) : base(correlationId, sourceId) { }
public void Can_Send_Error_To_Invalid_Transaction() { _transactionValidator.ValidateTransaction(Arg.Any <PublicEntry>()) .Returns(false); _transactionReceivedEvent.OnTransactionReceived(new TransactionBroadcast { PublicEntry = new PublicEntry() } .ToProtocolMessage(PeerIdHelper.GetPeerId(), CorrelationId.GenerateCorrelationId())).Should() .Be(ResponseCode.Error); _broadcastManager.DidNotReceiveWithAnyArgs()?.BroadcastAsync(default);
private async Task SendCommand(string dayId, CorrelationId correlationId, CausationId causationId) { await _commandStore.Send(new ArchiveDaySchedule(dayId), new CommandMetadata(correlationId, causationId)); }
public WoftamEvent(string property1, string property2) : base(CorrelationId.NewId(), SourceId.NullSourceId()) { Property1 = property1; Property2 = property2; }
bool Equals(CorrelationId other) { return(type == other.type && string.Equals(propertyName, other.propertyName) && propertyValue.Equals(other.propertyValue)); }
public Service(CorrelationId correlationId, ILogger<Service> logger, dynamic sideChannel) { _correlationId = correlationId; _logger = logger; _sideChannel = sideChannel; }
/// <summary> Write a <c>CorrelationId</c> value to the stream. </summary> internal static void Write(this IBinaryTokenStreamWriter @this, CorrelationId id) { @this.Write(id.ToByteArray()); }
/// <summary> /// Initializes a new instance of the <see cref="CommittedEventStream"/> class. /// </summary> /// <param name="sequence">The <see cref="CommitSequenceNumber" /> for this committed event stream.</param> /// <param name="source">The <see cref="VersionedEventSource" /> that this stream applies to.</param> /// <param name="id">The unique id in the form of a <see cref="CommitId" />.</param> /// <param name="correlationId">A <see cref="CorrelationId" /> used to relate this event stream to other actions in the system.</param> /// <param name="timestamp">A timestamp in the form of a <see cref="DateTimeOffset" /> representing when the stream was committed.</param> /// <param name="events">An enumerable of <see cref="EventEnvelope" /> representing the events that are committed in this commit.</param> public CommittedEventStream(CommitSequenceNumber sequence, VersionedEventSource source, CommitId id, CorrelationId correlationId, DateTimeOffset timestamp, EventStream events) { Sequence = sequence; Source = source; Id = id; Timestamp = timestamp; CorrelationId = correlationId; Events = events; LastEventVersion = source.ToCommittedEventVersion(sequence); }
public async Task <bool> QueryPeerTipAsync(PeerId recipientPeerId) { try { PeerClient.SendMessage(new MessageDto( new LatestDeltaHashRequest().ToProtocolMessage(PeerId, CorrelationId.GenerateCorrelationId()), recipientPeerId )); using (CancellationTokenProvider.CancellationTokenSource) { await QueryTipResponseMessageStreamer .FirstAsync(a => a != null && a.PeerId.PublicKey.SequenceEqual(recipientPeerId.PublicKey) && a.PeerId.Ip.SequenceEqual(recipientPeerId.Ip)) .ToTask(CancellationTokenProvider.CancellationTokenSource.Token) .ConfigureAwait(false); } } catch (OperationCanceledException) { return(false); } catch (Exception e) { Logger.Error(e, nameof(QueryPeerTipAsync)); return(false); } return(true); }
public async Task Can_Process_DeltaHeightRequest_Correctly() { var fakeContext = Substitute.For <IChannelHandlerContext>(); var deltaHistoryRequestMessage = new DeltaHistoryRequest(); var channeledAny = new ObserverDto(fakeContext, deltaHistoryRequestMessage.ToProtocolMessage(PeerIdHelper.GetPeerId(), CorrelationId.GenerateCorrelationId() ) ); var observableStream = new[] { channeledAny }.ToObservable(_testScheduler); _deltaHistoryRequestObserver.StartObserving(observableStream); _testScheduler.Start(); var response = new DeltaHistoryResponse(); var hp = new HashProvider(HashingAlgorithm.GetAlgorithmMetadata("keccak-256")); var lastDeltaHash = hp.ComputeMultiHash(ByteUtil.GenerateRandomByteArray(32)); for (uint x = 0; x < 10; x++) { var delta = new Delta { PreviousDeltaDfsHash = lastDeltaHash.Digest.ToByteString() }; var index = new DeltaIndex { Height = 10, Cid = delta.ToByteString() }; response.DeltaIndex.Add(index); lastDeltaHash = hp.ComputeMultiHash(ByteUtil.GenerateRandomByteArray(32)); } await fakeContext.Channel.ReceivedWithAnyArgs(1) .WriteAndFlushAsync(response.ToProtocolMessage(PeerIdHelper.GetPeerId(), CorrelationId.GenerateCorrelationId())).ConfigureAwait(false); _subbedLogger.ReceivedWithAnyArgs(1); }
private void UnregisterCallback(CorrelationId id) { CallbackData ignore; callbacks.TryRemove(id, out ignore); }
/// <summary> /// Initializes a new instance of the <see cref="CommandRequest"/> class. /// </summary> /// <param name="correlationId"><see cref="CorrelationId"/> for the request.</param> /// <param name="artifactId"><see cref="ArtifactId">Identifier</see> of the command.</param> /// <param name="generation"><see cref="ArtifactGeneration">Generation</see> of the command.</param> /// <param name="content">Content of the command.</param> public CommandRequest(CorrelationId correlationId, ArtifactId artifactId, ArtifactGeneration generation, IDictionary <string, object> content) { CorrelationId = correlationId; Type = new Artifact(artifactId, generation); Content = content; }
public void TrySendRequestCompletionToUser(string signalName, CorrelationId correlationId, UserIdentity user, Dictionary <string, object> values = null) { _wsRequestStatusService.TrySendRequestCompletionToUser(signalName, correlationId, user, values); }
public CycleProgressInfo Update() { int height = Services.BlockExplorerService.GetCurrentHeight(); CycleParameters cycle; CyclePhase phase; if (ClientChannelNegotiation == null) { cycle = Parameters.CycleGenerator.GetRegisteringCycle(height); phase = CyclePhase.Registration; } else { cycle = ClientChannelNegotiation.GetCycle(); var phases = new CyclePhase[] { CyclePhase.Registration, CyclePhase.ClientChannelEstablishment, CyclePhase.TumblerChannelEstablishment, CyclePhase.PaymentPhase, CyclePhase.TumblerCashoutPhase, CyclePhase.ClientCashoutPhase }; if (!phases.Any(p => cycle.IsInPhase(p, height))) { return(null); } phase = phases.First(p => cycle.IsInPhase(p, height)); } Logs.Client.LogInformation(Environment.NewLine); var period = cycle.GetPeriods().GetPeriod(phase); var blocksLeft = period.End - height; Logs.Client.LogInformation($"Cycle {cycle.Start} ({Status})"); Logs.Client.LogInformation($"{cycle.ToString(height)} in phase {phase} ({blocksLeft} more blocks)"); var previousState = Status; var progressInfo = new CycleProgressInfo(period, height, blocksLeft, cycle.Start, Status, phase, $"{cycle.ToString(height)} in phase {phase} ({blocksLeft} more blocks)"); TumblerClient bob = null, alice = null; try { var correlation = SolverClientSession == null ? CorrelationId.Zero : new CorrelationId(SolverClientSession.Id); FeeRate feeRate = null; switch (phase) { case CyclePhase.Registration: if (Status == PaymentStateMachineStatus.New) { bob = Runtime.CreateTumblerClient(cycle.Start, Identity.Bob); //Client asks for voucher var voucherResponse = bob.AskUnsignedVoucher(); NeedSave = true; //Client ensures he is in the same cycle as the tumbler (would fail if one tumbler or client's chain isn't sync) var tumblerCycle = Parameters.CycleGenerator.GetCycle(voucherResponse.CycleStart); Assert(tumblerCycle.Start == cycle.Start, "invalid-phase"); //Saving the voucher for later StartCycle = cycle.Start; ClientChannelNegotiation = new ClientChannelNegotiation(Parameters, cycle.Start); ClientChannelNegotiation.ReceiveUnsignedVoucher(voucherResponse); Status = PaymentStateMachineStatus.Registered; } break; case CyclePhase.ClientChannelEstablishment: if (Status == PaymentStateMachineStatus.Registered) { alice = Runtime.CreateTumblerClient(cycle.Start, Identity.Alice); var key = alice.RequestTumblerEscrowKey(); ClientChannelNegotiation.ReceiveTumblerEscrowKey(key.PubKey, key.KeyIndex); //Client create the escrow var escrowTxOut = ClientChannelNegotiation.BuildClientEscrowTxOut(); feeRate = GetFeeRate(); Transaction clientEscrowTx = null; try { clientEscrowTx = Services.WalletService.FundTransactionAsync(escrowTxOut, feeRate).GetAwaiter().GetResult(); } catch (NotEnoughFundsException ex) { Logs.Client.LogInformation($"Not enough funds in the wallet to tumble. Missing about {ex.Missing}. Denomination is {Parameters.Denomination}."); break; } NeedSave = true; var redeemDestination = Services.WalletService.GenerateAddressAsync().GetAwaiter().GetResult().ScriptPubKey; var channelId = new uint160(RandomUtils.GetBytes(20)); SolverClientSession = ClientChannelNegotiation.SetClientSignedTransaction(channelId, clientEscrowTx, redeemDestination); correlation = new CorrelationId(SolverClientSession.Id); Tracker.AddressCreated(cycle.Start, TransactionType.ClientEscrow, escrowTxOut.ScriptPubKey, correlation); Tracker.TransactionCreated(cycle.Start, TransactionType.ClientEscrow, clientEscrowTx.GetHash(), correlation); Services.BlockExplorerService.TrackAsync(escrowTxOut.ScriptPubKey).GetAwaiter().GetResult(); var redeemTx = SolverClientSession.CreateRedeemTransaction(feeRate); Tracker.AddressCreated(cycle.Start, TransactionType.ClientRedeem, redeemDestination, correlation); //redeemTx does not be to be recorded to the tracker, this is TrustedBroadcastService job Services.BroadcastService.BroadcastAsync(clientEscrowTx).GetAwaiter().GetResult(); Services.TrustedBroadcastService.Broadcast(cycle.Start, TransactionType.ClientRedeem, correlation, redeemTx); Status = PaymentStateMachineStatus.ClientChannelBroadcasted; } else if (Status == PaymentStateMachineStatus.ClientChannelBroadcasted) { alice = Runtime.CreateTumblerClient(cycle.Start, Identity.Alice); TransactionInformation clientTx = GetTransactionInformation(SolverClientSession.EscrowedCoin, true); var state = ClientChannelNegotiation.GetInternalState(); if (clientTx != null && clientTx.Confirmations >= cycle.SafetyPeriodDuration) { Logs.Client.LogInformation($"Client escrow reached {cycle.SafetyPeriodDuration} confirmations"); //Client asks the public key of the Tumbler and sends its own alice.BeginSignVoucher(new SignVoucherRequest { MerkleProof = clientTx.MerkleProof, Transaction = clientTx.Transaction, KeyReference = state.TumblerEscrowKeyReference, UnsignedVoucher = state.BlindedVoucher, Cycle = cycle.Start, ClientEscrowKey = state.ClientEscrowKey.PubKey, ChannelId = SolverClientSession.Id }); NeedSave = true; Status = PaymentStateMachineStatus.TumblerVoucherSigning; } } else if (Status == PaymentStateMachineStatus.TumblerVoucherSigning) { alice = Runtime.CreateTumblerClient(cycle.Start, Identity.Alice); var voucher = alice.EndSignVoucher(SolverClientSession.Id); if (voucher != null) { ClientChannelNegotiation.CheckVoucherSolution(voucher); NeedSave = true; Status = PaymentStateMachineStatus.TumblerVoucherObtained; } } break; case CyclePhase.TumblerChannelEstablishment: if (Status == PaymentStateMachineStatus.TumblerVoucherObtained) { bob = Runtime.CreateTumblerClient(cycle.Start, Identity.Bob); Logs.Client.LogInformation("Begin ask to open the channel..."); //Client asks the Tumbler to make a channel var bobEscrowInformation = ClientChannelNegotiation.GetOpenChannelRequest(); uint160 channelId = null; try { channelId = bob.BeginOpenChannel(bobEscrowInformation); NeedSave = true; } catch (Exception ex) { if (ex.Message.Contains("tumbler-insufficient-funds")) { Logs.Client.LogWarning("The tumbler server has not enough funds and can't open a channel for now"); break; } throw; } ClientChannelNegotiation.SetChannelId(channelId); Status = PaymentStateMachineStatus.TumblerChannelCreating; } else if (Status == PaymentStateMachineStatus.TumblerChannelCreating) { bob = Runtime.CreateTumblerClient(cycle.Start, Identity.Bob); var tumblerEscrow = bob.EndOpenChannel(cycle.Start, ClientChannelNegotiation.GetInternalState().ChannelId); if (tumblerEscrow == null) { Logs.Client.LogInformation("Tumbler escrow still creating..."); break; } NeedSave = true; if (tumblerEscrow.OutputIndex >= tumblerEscrow.Transaction.Outputs.Count) { Logs.Client.LogError("Tumbler escrow output out-of-bound"); Status = PaymentStateMachineStatus.Wasted; break; } var txOut = tumblerEscrow.Transaction.Outputs[tumblerEscrow.OutputIndex]; var outpoint = new OutPoint(tumblerEscrow.Transaction.GetHash(), tumblerEscrow.OutputIndex); var escrowCoin = new Coin(outpoint, txOut).ToScriptCoin(ClientChannelNegotiation.GetTumblerEscrowParameters(tumblerEscrow.EscrowInitiatorKey).ToScript()); PromiseClientSession = ClientChannelNegotiation.ReceiveTumblerEscrowedCoin(escrowCoin); Logs.Client.LogInformation("Tumbler expected escrowed coin received"); //Tell to the block explorer we need to track that address (for checking if it is confirmed in payment phase) Services.BlockExplorerService.TrackAsync(PromiseClientSession.EscrowedCoin.ScriptPubKey).GetAwaiter().GetResult(); Services.BlockExplorerService.TrackPrunedTransactionAsync(tumblerEscrow.Transaction, tumblerEscrow.MerkleProof).GetAwaiter().GetResult(); Tracker.AddressCreated(cycle.Start, TransactionType.TumblerEscrow, PromiseClientSession.EscrowedCoin.ScriptPubKey, correlation); Tracker.TransactionCreated(cycle.Start, TransactionType.TumblerEscrow, PromiseClientSession.EscrowedCoin.Outpoint.Hash, correlation); Services.BroadcastService.BroadcastAsync(tumblerEscrow.Transaction).GetAwaiter().GetResult(); //Channel is done, now need to run the promise protocol to get valid puzzle var cashoutDestination = DestinationWallet.GetNewDestination(); Tracker.AddressCreated(cycle.Start, TransactionType.TumblerCashout, cashoutDestination, correlation); feeRate = GetFeeRate(); var sigReq = PromiseClientSession.CreateSignatureRequest(cashoutDestination, feeRate); var commitments = bob.SignHashes(PromiseClientSession.Id, sigReq); var revelation = PromiseClientSession.Reveal(commitments); var proof = bob.CheckRevelation(PromiseClientSession.Id, revelation); var puzzle = PromiseClientSession.CheckCommitmentProof(proof); SolverClientSession.AcceptPuzzle(puzzle); Status = PaymentStateMachineStatus.TumblerChannelCreated; } else if (Status == PaymentStateMachineStatus.TumblerChannelCreated) { CheckTumblerChannelSecured(cycle); } break; case CyclePhase.PaymentPhase: //Could have confirmed during safe period //Only check for the first block when period start, //else Tumbler can know deanonymize you based on the timing of first Alice request if the transaction was not confirmed previously if (Status == PaymentStateMachineStatus.TumblerChannelCreated && height == period.Start) { CheckTumblerChannelSecured(cycle); } //No "else if" intended if (Status == PaymentStateMachineStatus.TumblerChannelSecured) { alice = Runtime.CreateTumblerClient(cycle.Start, Identity.Alice); Logs.Client.LogDebug("Starting the puzzle solver protocol..."); var puzzles = SolverClientSession.GeneratePuzzles(); alice.BeginSolvePuzzles(SolverClientSession.Id, puzzles); NeedSave = true; Status = PaymentStateMachineStatus.ProcessingPayment; } else if (Status == PaymentStateMachineStatus.ProcessingPayment) { feeRate = GetFeeRate(); alice = Runtime.CreateTumblerClient(cycle.Start, Identity.Alice); var commitments = alice.EndSolvePuzzles(SolverClientSession.Id); NeedSave = true; if (commitments == null) { Logs.Client.LogDebug("Still solving puzzles..."); break; } var revelation2 = SolverClientSession.Reveal(commitments); var solutionKeys = alice.CheckRevelation(SolverClientSession.Id, revelation2); var blindFactors = SolverClientSession.GetBlindFactors(solutionKeys); var offerInformation = alice.CheckBlindFactors(SolverClientSession.Id, blindFactors); var offerSignature = SolverClientSession.SignOffer(offerInformation); var offerRedeem = SolverClientSession.CreateOfferRedeemTransaction(feeRate); Logs.Client.LogDebug("Puzzle solver protocol ended..."); //May need to find solution in the fulfillment transaction Services.BlockExplorerService.TrackAsync(offerRedeem.PreviousScriptPubKey).GetAwaiter().GetResult(); Tracker.AddressCreated(cycle.Start, TransactionType.ClientOfferRedeem, SolverClientSession.GetInternalState().RedeemDestination, correlation); Services.TrustedBroadcastService.Broadcast(cycle.Start, TransactionType.ClientOfferRedeem, correlation, offerRedeem); try { solutionKeys = alice.FulfillOffer(SolverClientSession.Id, offerSignature); SolverClientSession.CheckSolutions(solutionKeys); var tumblingSolution = SolverClientSession.GetSolution(); var transaction = PromiseClientSession.GetSignedTransaction(tumblingSolution); Logs.Client.LogDebug("Got puzzle solution cooperatively from the tumbler"); Status = PaymentStateMachineStatus.PuzzleSolutionObtained; Services.TrustedBroadcastService.Broadcast(cycle.Start, TransactionType.TumblerCashout, correlation, new TrustedBroadcastRequest() { BroadcastAt = cycle.GetPeriods().ClientCashout.Start, Transaction = transaction }); if (Cooperative) { try { // No need to await for it, it is a just nice for the tumbler (we don't want the underlying socks connection cut before the escape key is sent) var signature = SolverClientSession.SignEscape(); alice.GiveEscapeKeyAsync(SolverClientSession.Id, signature).GetAwaiter().GetResult(); } catch (Exception ex) { Logs.Client.LogDebug(new EventId(), ex, "Exception while giving the escape key"); } Logs.Client.LogInformation("Gave escape signature to the tumbler"); } } catch (Exception ex) { Status = PaymentStateMachineStatus.UncooperativeTumbler; Logs.Client.LogWarning("The tumbler did not gave puzzle solution cooperatively"); Logs.Client.LogWarning(ex.ToString()); } } break; case CyclePhase.ClientCashoutPhase: //If the tumbler is uncooperative, he published solutions on the blockchain if (Status == PaymentStateMachineStatus.UncooperativeTumbler) { var transactions = Services.BlockExplorerService.GetTransactionsAsync(SolverClientSession.GetInternalState().OfferCoin.ScriptPubKey, false).GetAwaiter().GetResult(); if (transactions.Count != 0) { SolverClientSession.CheckSolutions(transactions.Select(t => t.Transaction).ToArray()); Logs.Client.LogInformation("Puzzle solution recovered from tumbler's fulfill transaction"); NeedSave = true; Status = PaymentStateMachineStatus.PuzzleSolutionObtained; var tumblingSolution = SolverClientSession.GetSolution(); var transaction = PromiseClientSession.GetSignedTransaction(tumblingSolution); Tracker.TransactionCreated(cycle.Start, TransactionType.TumblerCashout, transaction.GetHash(), correlation); Services.BroadcastService.BroadcastAsync(transaction).GetAwaiter().GetResult(); } } break; } } catch (InvalidStateException ex) { Logs.Client.LogDebug(new EventId(), ex, "Client side Invalid State, the payment is wasted"); Status = PaymentStateMachineStatus.Wasted; } catch (Exception ex) when(ex.Message.IndexOf("invalid-state", StringComparison.OrdinalIgnoreCase) >= 0) { Logs.Client.LogDebug(new EventId(), ex, "Tumbler side Invalid State, the payment is wasted"); Status = PaymentStateMachineStatus.Wasted; } finally { if (previousState != Status) { Logs.Client.LogInformation($"Status changed {previousState} => {Status}"); } if (alice != null && bob != null) { throw new InvalidOperationException("Bob and Alice have been both initialized, please report the bug to NTumbleBit developers"); } if (alice != null) { alice.Dispose(); } if (bob != null) { bob.Dispose(); } } return(progressInfo); }
// Other simple types /// <summary> Write a <c>CorrelationId</c> value to the stream. </summary> internal void Write(CorrelationId id) { Write(id.ToByteArray()); }
public AddSensorRequest(CorrelationId correlationId, SensorIdentifier sensorId) { CorrelationId = correlationId; SensorId = sensorId; }
private void UnRegisterCallback(CorrelationId id) { CallbackData ignore; callbacks.TryRemove(id, out ignore); }
internal static bool TryReadSimpleType <TReader>(this TReader @this, out object result, out SerializationTokenType token) where TReader : IBinaryTokenStreamReader { token = @this.ReadToken(); switch (token) { case SerializationTokenType.True: result = true; break; case SerializationTokenType.False: result = false; break; case SerializationTokenType.Null: result = null; break; case SerializationTokenType.Object: result = new object(); break; case SerializationTokenType.Int: result = @this.ReadInt(); break; case SerializationTokenType.Uint: result = @this.ReadUInt(); break; case SerializationTokenType.Short: result = @this.ReadShort(); break; case SerializationTokenType.Ushort: result = @this.ReadUShort(); break; case SerializationTokenType.Long: result = @this.ReadLong(); break; case SerializationTokenType.Ulong: result = @this.ReadULong(); break; case SerializationTokenType.Byte: result = @this.ReadByte(); break; case SerializationTokenType.Sbyte: result = @this.ReadSByte(); break; case SerializationTokenType.Float: result = @this.ReadFloat(); break; case SerializationTokenType.Double: result = @this.ReadDouble(); break; case SerializationTokenType.Decimal: result = @this.ReadDecimal(); break; case SerializationTokenType.String: result = @this.ReadString(); break; case SerializationTokenType.Character: result = @this.ReadChar(); break; case SerializationTokenType.Guid: if (@this is BinaryTokenStreamReader2 reader) { result = reader.ReadGuid(); } else { var bytes = @this.ReadBytes(16); result = new Guid(bytes); } break; case SerializationTokenType.Date: result = DateTime.FromBinary(@this.ReadLong()); break; case SerializationTokenType.TimeSpan: result = new TimeSpan(@this.ReadLong()); break; case SerializationTokenType.GrainId: result = @this.ReadGrainId(); break; case SerializationTokenType.ActivationId: result = @this.ReadActivationId(); break; case SerializationTokenType.SiloAddress: result = @this.ReadSiloAddress(); break; case SerializationTokenType.ActivationAddress: result = @this.ReadActivationAddress(); break; case SerializationTokenType.IpAddress: result = @this.ReadIPAddress(); break; case SerializationTokenType.IpEndPoint: result = @this.ReadIPEndPoint(); break; case SerializationTokenType.CorrelationId: result = new CorrelationId(@this.ReadLong()); break; default: result = null; return(false); } return(true); }