protected override void ProcessTx(TxPayload payload) { if (!MempoolService.TrustedNodeMode) { base.ProcessTx(payload); } }
protected virtual void ProcessTx(TxPayload payload) { Transaction transaction = payload.Object; transaction.PrecomputeHash(false, true); MempoolService.Process(transaction); }
/// <summary> /// Handler for processing node messages. /// Handles the following message payloads: TxPayload, MempoolPayload, GetDataPayload, InvPayload. /// </summary> /// <param name="node">Node sending the message.</param> /// <param name="message">Incoming message.</param> private Task AttachedNode_MessageReceivedAsync(Node node, IncomingMessage message) { TxPayload txPayload = message.Message.Payload as TxPayload; if (txPayload != null) { return(this.ProcessTxPayloadAsync(node, txPayload)); } MempoolPayload mempoolPayload = message.Message.Payload as MempoolPayload; if (mempoolPayload != null) { return(this.SendMempoolPayload(node, mempoolPayload)); } GetDataPayload getDataPayload = message.Message.Payload as GetDataPayload; if (getDataPayload != null) { return(this.ProcessGetDataAsync(node, getDataPayload)); } InvPayload invPayload = message.Message.Payload as InvPayload; if (invPayload != null) { return(this.ProcessInvAsync(node, invPayload)); } return(Task.CompletedTask); }
void NewNodeMessage(IncomingMessage message) { if (message.Message.Payload is VerAckPayload) { _Nodes.Add(message.Node); } if (message.Message.Payload is InvPayload) { InvPayload invPayload = (InvPayload)message.Message.Payload; message.Node.SendMessage(new GetDataPayload(invPayload.Inventory.ToArray())); } if (message.Message.Payload is TxPayload) { TxPayload txPayload = (TxPayload)message.Message.Payload; _ReceivedTransactions.AddOrUpdate(txPayload.Object.GetHash(), txPayload.Object, (k, v) => v); } if (message.Message.Payload is GetHeadersPayload) { var headers = (GetHeadersPayload)message.Message.Payload; var fork = _Server.ChainBuilder.Chain.FindFork(headers.BlockLocators); var response = _Server.ChainBuilder.Chain .ToEnumerable(true) .TakeWhile(f => f.HashBlock != fork.HashBlock && f.HashBlock != headers.HashStop) .Select(f => f.Header) .ToArray(); HeadersPayload res = new HeadersPayload(); res.Headers.AddRange(response); message.Node.SendMessage(res); } if (message.Message.Payload is GetDataPayload) { Transaction tx; Block block; var getData = message.Message.Payload as GetDataPayload; foreach (var inv in getData.Inventory) { if (inv.Type == InventoryType.MSG_TX) { if (_Transactions.TryGetValue(inv.Hash, out tx)) { message.Node.SendMessage(new TxPayload(tx)); } } if (inv.Type == InventoryType.MSG_BLOCK) { if (_Blocks.TryGetValue(inv.Hash, out block)) { message.Node.SendMessage(new BlockPayload(block)); } } } } }
public void TryDeserialize_FailTest(FastStreamReader stream, MockDeserializableTx tx, string expErr) { TxPayload pl = new TxPayload() { Tx = tx }; bool b = pl.TryDeserialize(stream, out string error); Assert.False(b); Assert.Equal(expErr, error); // Mock tx has its own tests. }
private void ProcessTxPayload(TxPayload txPayload) { Transaction transaction = txPayload.Obj; uint256 trxHash = transaction.GetHash(); if (this.notifiedTransactions.TransactionsReceived.ContainsKey(trxHash)) { return; } // send the transaction to the notifier this.signals.Publish(new TransactionReceived(transaction)); this.notifiedTransactions.TransactionsReceived.TryAdd(trxHash, trxHash); }
/// <inheritdoc /> public bool SendTransaction(string transactionHex) { // TODO move this to a behavior on the full node // parse transaction Transaction transaction = Transaction.Parse(transactionHex); TxPayload payload = new TxPayload(transaction); foreach (var node in this.connectionManager.ConnectedNodes) { node.SendMessage(payload); } return(true); }
private void ProcessTxPayload(TxPayload txPayload) { var transaction = txPayload.Obj; var trxHash = transaction.GetHash(); if (this.notifiedTransactions.TransactionsReceived.ContainsKey(trxHash)) { return; } // send the transaction to the notifier this.transactionNotification.Notify(transaction); this.notifiedTransactions.TransactionsReceived.TryAdd(trxHash, trxHash); }
public void TryDeserializeTest() { TxPayload pl = new TxPayload() { Tx = new MockDeserializableTx(0, 3) }; FastStreamReader stream = new FastStreamReader(new byte[3]); bool b = pl.TryDeserialize(stream, out string error); Assert.True(b, error); Assert.Null(error); // Mock tx has its own tests. Assert.Equal(PayloadType.Tx, pl.PayloadType); }
/// <summary> /// Processing of the transaction payload message from peer. /// Adds transaction from the transaction payload to the memory pool. /// </summary> /// <param name="peer">Peer sending the message.</param> /// <param name="transactionPayload">The payload for the message.</param> private async Task ProcessTxPayloadAsync(INetworkPeer peer, TxPayload transactionPayload) { this.logger.LogTrace("({0}:'{1}',{2}.{3}:{4})", nameof(peer), peer.RemoteSocketEndpoint, nameof(transactionPayload), nameof(transactionPayload.Obj), transactionPayload?.Obj?.GetHash()); Transaction trx = transactionPayload.Obj; uint256 trxHash = trx.GetHash(); // add to local filter lock (this.lockObject) { this.filterInventoryKnown.Add(trxHash); } this.logger.LogTrace("Added transaction ID '{0}' to known inventory filter.", trxHash); var state = new MempoolValidationState(true); if (!await this.orphans.AlreadyHaveAsync(trxHash) && await this.validator.AcceptToMemoryPool(state, trx)) { await this.validator.SanityCheck(); this.RelayTransaction(trxHash); this.signals.SignalTransaction(trx); long mmsize = state.MempoolSize; long memdyn = state.MempoolDynamicSize; this.logger.LogInformation("Transaction ID '{0}' accepted to memory pool from peer '{1}' (poolsz {2} txn, {3} kb).", trxHash, peer.RemoteSocketEndpoint, mmsize, memdyn / 1000); await this.orphans.ProcessesOrphansAsync(this, trx); } else if (state.MissingInputs) { this.orphans.ProcessesOrphansMissingInputs(peer, trx); } else { if (!trx.HasWitness && state.CorruptionPossible) { } // TODO: Implement Processes whitelistforcerelay } if (state.IsInvalid) { this.logger.LogInformation("Transaction ID '{0}' from peer '{1}' was not accepted. Invalid state of '{2}'.", trxHash, peer.RemoteSocketEndpoint, state); } this.logger.LogTrace("(-)"); }
public void SerializeTest() { TxPayload pl = new TxPayload() { Tx = new MockSerializableTx(new byte[] { 1, 2, 3 }) }; FastStream stream = new FastStream(); pl.Serialize(stream); byte[] actual = pl.Serialize(); byte[] expected = new byte[] { 1, 2, 3 }; Assert.Equal(expected, stream.ToByteArray()); Assert.Equal(expected, actual); }
private async Task ProcessTxPayloadAsync(Node node, TxPayload transactionPayload) { var trx = transactionPayload.Object; var trxHash = trx.GetHash(); // add to local filter await this.manager.MempoolScheduler.WriteAsync(() => this.filterInventoryKnown.TryAdd(trxHash, trxHash)); var state = new MempoolValidationState(true); if (!await this.orphans.AlreadyHave(trxHash) && await this.validator.AcceptToMemoryPool(state, trx)) { await this.validator.SanityCheck(); await this.RelayTransaction(trxHash).ConfigureAwait(false); this.signals.Transactions.Broadcast(trx); var mmsize = state.MempoolSize; var memdyn = state.MempoolDynamicSize; Logging.Logs.Mempool.LogInformation( $"AcceptToMemoryPool: peer={node.Peer.Endpoint}: accepted {trxHash} (poolsz {mmsize} txn, {memdyn/1000} kb)"); await this.orphans.ProcessesOrphans(this, trx); } else if (state.MissingInputs) { await this.orphans.ProcessesOrphansMissingInputs(node, trx); } else { if (!trx.HasWitness && state.CorruptionPossible) { } // TODO: Implement Processes whitelistforcerelay } if (state.IsInvalid) { Logging.Logs.Mempool.LogInformation($"{trxHash} from peer={node.Peer.Endpoint} was not accepted: {state}"); } }
void _SenderNode_MessageReceived(Node node, IncomingMessage message) { if (message.Message.Payload is GetDataPayload) { var getData = (GetDataPayload)message.Message.Payload; foreach (var data in getData.Inventory) { if (data.Type == InventoryType.MSG_TX && _BroadcastedTransactions.ContainsKey(data.Hash)) { var result = _BroadcastedTransactions[data.Hash]; var tx = new TxPayload(result.Transaction); node.SendMessage(tx); ListenerTrace.Info("Broadcasted " + data.Hash); try { Configuration.GetBroadcastedTransactionsListenable().CloudTable.Execute(TableOperation.Delete(result.ToEntity())); } catch (StorageException) { } } } } if (message.Message.Payload is RejectPayload) { var reject = (RejectPayload)message.Message.Payload; uint256 txId = reject.Hash; if (txId != null && _BroadcastedTransactions.ContainsKey(txId)) { ListenerTrace.Info("Broadcasted transaction rejected (" + reject.Code + ") " + txId); DeleteBroadcasted(txId); if (reject.Code != RejectCode.DUPLICATE) { UpdateBroadcastState(txId, reject.Code.ToString()); } } } if (message.Message.Payload is PongPayload) { ListenerTrace.Verbose("Pong"); } }
void AttachedNode_MessageReceived(Node node, IncomingMessage message) { TxPayload txPayload = message.Message.Payload as TxPayload; if (txPayload != null) { Transaction tx; var hash = txPayload.Object.GetHash(); if (_Wallet._BroadcastedTransaction.TryRemove(hash, out tx)) { _Broadcasting.TryRemove(hash, out tx); _Wallet.OnTransactionBroadcasted(tx, node); } } RejectPayload reject = message.Message.Payload as RejectPayload; if (reject != null) { Transaction tx; if (_Broadcasting.TryRemove(reject.Hash, out tx)) { _Wallet.OnTransactionRejected(tx, node); } } GetDataPayload getData = message.Message.Payload as GetDataPayload; if (getData != null) { foreach (var inventory in getData.Inventory.Where(i => i.Type == InventoryType.MSG_TX)) { Transaction tx; if (_Broadcasting.TryRemove(inventory.Hash, out tx)) { node.SendMessageAsync(new TxPayload(tx)); } } } }
private async Task ProcessGetDataAsync(Node node, GetDataPayload payload) { if (payload.Inventory.Count > MaxInvSize) { Logger.LogDebug($"Received inventory too big. {nameof(MaxInvSize)}: {MaxInvSize}, Node: {node.RemoteSocketEndpoint}"); return; } foreach (var inv in payload.Inventory.Where(inv => inv.Type.HasFlag(InventoryType.MSG_TX))) { if (MempoolService.TryGetFromBroadcastStore(inv.Hash, out TransactionBroadcastEntry entry)) // If we have the transaction to be broadcasted then broadcast it now. { if (entry.NodeRemoteSocketEndpoint != node.RemoteSocketEndpoint.ToString()) { continue; // Would be strange. It could be some kind of attack. } try { var txPayload = new TxPayload(entry.Transaction); if (!node.IsConnected) { Logger.LogInfo($"Could not serve transaction. Node ({node.RemoteSocketEndpoint}) is not connected anymore: {entry.TransactionId}."); } else { await node.SendMessageAsync(txPayload).ConfigureAwait(false); entry.MakeBroadcasted(); Logger.LogInfo($"Successfully served transaction to node ({node.RemoteSocketEndpoint}): {entry.TransactionId}."); } } catch (Exception ex) { Logger.LogInfo(ex); } } } }
/// <summary> /// Handler for processing node messages. /// Handles the following message payloads: TxPayload, MempoolPayload, GetDataPayload, InvPayload. /// </summary> /// <param name="node">Node sending the message.</param> /// <param name="message">Incoming message.</param> private Task ProcessMessageAsync(Node node, IncomingMessage message) { this.logger.LogTrace("({0}:'{1}',{2}:'{3}')", nameof(node), node.RemoteSocketEndpoint, nameof(message), message.Message.Command); TxPayload txPayload = message.Message.Payload as TxPayload; if (txPayload != null) { this.logger.LogTrace("(-)[TX_PAYLOAD]"); return(this.ProcessTxPayloadAsync(node, txPayload)); } MempoolPayload mempoolPayload = message.Message.Payload as MempoolPayload; if (mempoolPayload != null) { this.logger.LogTrace("(-)[MEMPOOL_PAYLOAD]"); return(this.SendMempoolPayloadAsync(node, mempoolPayload)); } GetDataPayload getDataPayload = message.Message.Payload as GetDataPayload; if (getDataPayload != null) { this.logger.LogTrace("(-)[GET_DATA_PAYLOAD]"); return(this.ProcessGetDataAsync(node, getDataPayload)); } InvPayload invPayload = message.Message.Payload as InvPayload; if (invPayload != null) { this.logger.LogTrace("(-)[INV_PAYLOAD]"); return(this.ProcessInvAsync(node, invPayload)); } this.logger.LogTrace("(-)"); return(Task.CompletedTask); }
/// <inheritdoc /> public bool SendTransaction(string transactionHex) { Guard.NotEmpty(transactionHex, nameof(transactionHex)); // TODO move this to a behavior to a dedicated interface // parse transaction Transaction transaction = Transaction.Parse(transactionHex); // replace this we a dedicated WalletBroadcast interface // in a fullnode implementation this will validate with the // mempool and broadcast, in a lightnode this will push to // the wallet and then broadcast (we might add some basic validation if (this.mempoolValidator == null) { this.ProcessTransaction(transaction); } else { var state = new MempoolValidationState(false); if (!this.mempoolValidator.AcceptToMemoryPool(state, transaction).GetAwaiter().GetResult()) { return(false); } this.ProcessTransaction(transaction); } // broadcast to peers TxPayload payload = new TxPayload(transaction); foreach (var node in this.connectionManager.ConnectedNodes) { node.SendMessage(payload); } // we might want to create a behaviour that tracks how many times // the broadcast trasnactions was sent back to us by other peers return(true); }
private void ProcessTx(TxPayload payload) { Transaction transaction = payload.Object; MemPoolService.OnTransactionReceived(new SmartTransaction(transaction, Height.MemPool)); }
public static void Send(ConnectionType connectionType, TransactionInfo transactionInfo, int tryTimes = 1) { var monitor = new HttpMonitor(transactionInfo.Network); if (connectionType == ConnectionType.Http) { var client = new QBitNinjaClient(Convert.ToNBitcoinNetwork(transactionInfo.Network)); var transaction = FindTransaction(transactionInfo); var broadcastResponse = client.Broadcast(transaction).Result; if (!broadcastResponse.Success) { throw new Exception($"ErrorCode: {broadcastResponse.Error.ErrorCode}" + Environment.NewLine + broadcastResponse.Error.Reason); } } if (connectionType == ConnectionType.RandomNode) { var parameters = new NodeConnectionParameters(); var group = new NodesGroup(Convert.ToNBitcoinNetwork(transactionInfo.Network), parameters, new NodeRequirement { RequiredServices = NodeServices.Nothing }) { MaximumNodeConnection = 1 }; group.Connect(); while (group.ConnectedNodes.Count == 0) { Thread.Sleep(100); } var transaction = FindTransaction(transactionInfo); var payload = new TxPayload(transaction); group.ConnectedNodes.First().SendMessage(payload); } for (var i = 0; i < 10; i++) { try { monitor.GetTransactionInfo(transactionInfo.Id); } catch (NullReferenceException exception) { if (exception.Message != "Transaction does not exists") { throw; } Thread.Sleep(1000); continue; } if (i == 10) { if (tryTimes == 1) { throw new Exception("Transaction has not been broadcasted, try again!"); } Send(connectionType, transactionInfo, tryTimes - 1); } break; } }
/// <summary> /// Processing of the transaction payload message from peer. /// Adds transaction from the transaction payload to the memory pool. /// </summary> /// <param name="peer">Peer sending the message.</param> /// <param name="transactionPayload">The payload for the message.</param> private async Task ProcessTxPayloadAsync(INetworkPeer peer, TxPayload transactionPayload) { // Stop processing the transaction early if we are in blocks only mode. if (this.isBlocksOnlyMode) { this.logger.LogInformation("Transaction sent in violation of protocol from peer '{0}'.", peer.RemoteSocketEndpoint); this.logger.LogTrace("(-)[BLOCKSONLY]"); return; } Transaction trx = transactionPayload.Obj; uint256 trxHash = trx.GetHash(); // add to local filter lock (this.lockObject) { this.filterInventoryKnown.Add(trxHash); } this.logger.LogTrace("Added transaction ID '{0}' to known inventory filter.", trxHash); var state = new MempoolValidationState(true); if (!await this.orphans.AlreadyHaveAsync(trxHash) && await this.validator.AcceptToMemoryPool(state, trx)) { await this.validator.SanityCheck(); this.RelayTransaction(trxHash); this.signals.SignalTransaction(trx); long mmsize = state.MempoolSize; long memdyn = state.MempoolDynamicSize; this.logger.LogInformation("Transaction ID '{0}' accepted to memory pool from peer '{1}' (poolsz {2} txn, {3} kb).", trxHash, peer.RemoteSocketEndpoint, mmsize, memdyn / 1000); await this.orphans.ProcessesOrphansAsync(this, trx); } else if (state.MissingInputs) { this.orphans.ProcessesOrphansMissingInputs(peer, trx); } else { // Do not use rejection cache for witness transactions or // witness-stripped transactions, as they can have been malleated. // See https://github.com/bitcoin/bitcoin/issues/8279 for details. if (!trx.HasWitness && !state.CorruptionPossible) { this.orphans.AddToRecentRejects(trxHash); } // Always relay transactions received from whitelisted peers, even // if they were already in the mempool or rejected from it due // to policy, allowing the node to function as a gateway for // nodes hidden behind it. // // Never relay transactions that we would assign a non-zero DoS // score for, as we expect peers to do the same with us in that // case. if (this.isPeerWhitelistedForRelay) { if (!state.IsInvalid) { this.logger.LogInformation("Force relaying transaction ID '{0}' from whitelisted peer '{1}'.", trxHash, peer.RemoteSocketEndpoint); this.RelayTransaction(trxHash); } else { this.logger.LogInformation("Not relaying invalid transaction ID '{0}' from whitelisted peer '{1}' ({2}).", trxHash, peer.RemoteSocketEndpoint, state); } } } if (state.IsInvalid) { this.logger.LogInformation("Transaction ID '{0}' from peer '{1}' was not accepted. Invalid state of '{2}'.", trxHash, peer.RemoteSocketEndpoint, state); } }
public static async Task SendAsync(string baseAddress, ConnectionType connectionType, TransactionInfo transactionInfo, int tryTimes = 1) { var monitor = new HttpMonitor(baseAddress, transactionInfo.Network); if (connectionType == ConnectionType.Http) { var client = new QBitNinjaClient(baseAddress, transactionInfo.Network.ToNBitcoinNetwork()); var transaction = FindTransaction(transactionInfo); var broadcastResponse = await client.Broadcast(transaction).ConfigureAwait(false); if (!broadcastResponse.Success) { throw new Exception($"ErrorCode: {broadcastResponse.Error.ErrorCode}" + Environment.NewLine + broadcastResponse.Error.Reason); } } if (connectionType == ConnectionType.RandomNode) { var parameters = new NodeConnectionParameters(); var group = new NodesGroup(transactionInfo.Network.ToNBitcoinNetwork(), parameters, new NodeRequirement { RequiredServices = NodeServices.Nothing }) { MaximumNodeConnection = 1 }; group.Connect(); while (group.ConnectedNodes.Count == 0) { await Task.Delay(100).ConfigureAwait(false); } var transaction = FindTransaction(transactionInfo); var payload = new TxPayload(transaction); group.ConnectedNodes.First().SendMessage(payload); } for (var i = 0; i < 10; i++) { try { var result = await monitor.GetTransactionInfoAsync(transactionInfo.Id); } catch (NullReferenceException exception) { if (exception.Message != "Transaction does not exists") { throw; } await Task.Delay(1000).ConfigureAwait(false); continue; } if (i == 10) { if (tryTimes == 1) { throw new Exception("Transaction has not been broadcasted, try again!"); } await SendAsync(baseAddress, connectionType, transactionInfo, tryTimes - 1) .ConfigureAwait(false); } break; } }
private void ProcessTx(TxPayload payload) { Transaction transaction = payload.Object; MempoolService.Process(transaction); }
private void ProcessTxPayload(TxPayload transactionPayload) { Transaction tx = transactionPayload.Object; MemPoolJob.TryAddNewTransaction(tx); }
void node_MessageReceived(Node node, IncomingMessage message) { if (_KnownInvs.Count == 1000) { _KnownInvs.Clear(); } if (message.Message.Payload is InvPayload) { var inv = (InvPayload)message.Message.Payload; foreach (var inventory in inv.Inventory) { Transaction tx; if (_Broadcasting.TryRemove(inventory.Hash, out tx)) { ListenerTrace.Info("Broadcasted reached mempool " + inventory); } } var getdata = new GetDataPayload(inv.Inventory.Where(i => i.Type == InventoryType.MSG_TX && _KnownInvs.TryAdd(i.Hash, i.Hash)).ToArray()); foreach (var data in getdata.Inventory) { data.Type = node.AddSupportedOptions(InventoryType.MSG_TX); } if (getdata.Inventory.Count > 0) { node.SendMessageAsync(getdata); } } if (message.Message.Payload is TxPayload) { var tx = ((TxPayload)message.Message.Payload).Object; ListenerTrace.Verbose("Received Transaction " + tx.GetHash()); _Indexer.IndexAsync(new TransactionEntry.Entity(tx.GetHash(), tx, null)) .ContinueWith(HandleException); _Indexer.IndexOrderedBalanceAsync(tx) .ContinueWith(HandleException); Async(() => { var txId = tx.GetHash(); List <OrderedBalanceChange> balances; using (_WalletsSlimLock.LockRead()) { balances = OrderedBalanceChange .ExtractWalletBalances(txId, tx, null, null, int.MaxValue, _Wallets) .AsEnumerable() .ToList(); } UpdateHDState(balances); _Indexer.IndexAsync(balances) .ContinueWith(HandleException); Task notify = null; using (_SubscriptionSlimLock.LockRead()) { var topic = Configuration.Topics.SendNotifications; notify = Task.WhenAll(_Subscriptions .GetNewTransactions() .Select(t => topic.AddAsync(new Notify() { SendAndForget = true, Notification = new Notification() { Subscription = t, Data = new NewTransactionNotificationData() { TransactionId = txId } } })).ToArray()); } notify.Wait(); }); var unused = Configuration.Topics.NewTransactions.AddAsync(tx) .ContinueWith(HandleException); } if (message.Message.Payload is BlockPayload) { var block = ((BlockPayload)message.Message.Payload).Object; var blockId = block.GetHash(); List <OrderedBalanceChange> balances = null; using (_WalletsSlimLock.LockRead()) { balances = block.Transactions.SelectMany(tx => OrderedBalanceChange.ExtractWalletBalances(null, tx, null, null, 0, _Wallets)).ToList(); } UpdateHDState(balances); } if (message.Message.Payload is HeadersPayload) { if (_Chain.Tip.HashBlock != _LastChainTip) { var header = _Chain.Tip.Header; _LastChainTip = _Chain.Tip.HashBlock; Configuration.Indexer.CreateIndexer().IndexChain(_Chain); Async(() => { CancellationTokenSource cancel = new CancellationTokenSource(TimeSpan.FromMinutes(30)); var repo = new CacheBlocksRepository(new NodeBlocksRepository(node)); TryLock(_LockBlocks, () => { new IndexBlocksTask(Configuration.Indexer) { EnsureIsSetup = false, }.Index(new BlockFetcher(_Indexer.GetCheckpoint(IndexerCheckpoints.Blocks), repo, _Chain) { CancellationToken = cancel.Token }, _Indexer.TaskScheduler); }); TryLock(_LockTransactions, () => { new IndexTransactionsTask(Configuration.Indexer) { EnsureIsSetup = false } .Index(new BlockFetcher(_Indexer.GetCheckpoint(IndexerCheckpoints.Transactions), repo, _Chain) { CancellationToken = cancel.Token }, _Indexer.TaskScheduler); }); TryLock(_LockWallets, () => { using (_WalletsSlimLock.LockRead()) { new IndexBalanceTask(Configuration.Indexer, _Wallets) { EnsureIsSetup = false } .Index(new BlockFetcher(_Indexer.GetCheckpoint(IndexerCheckpoints.Wallets), repo, _Chain) { CancellationToken = cancel.Token }, _Indexer.TaskScheduler); } }); TryLock(_LockBalance, () => { new IndexBalanceTask(Configuration.Indexer, null) { EnsureIsSetup = false }.Index(new BlockFetcher(_Indexer.GetCheckpoint(IndexerCheckpoints.Balances), repo, _Chain) { CancellationToken = cancel.Token }, _Indexer.TaskScheduler); }); TryLock(_LockSubscriptions, () => { using (_SubscriptionSlimLock.LockRead()) { new IndexNotificationsTask(Configuration, _Subscriptions) { EnsureIsSetup = false, } .Index(new BlockFetcher(_Indexer.GetCheckpointRepository().GetCheckpoint("subscriptions"), repo, _Chain) { CancellationToken = cancel.Token }, _Indexer.TaskScheduler); } }); cancel.Dispose(); var unused = _Configuration.Topics.NewBlocks.AddAsync(header); }); } } if (message.Message.Payload is GetDataPayload) { var getData = (GetDataPayload)message.Message.Payload; foreach (var data in getData.Inventory) { Transaction tx = null; if (data.Type == InventoryType.MSG_TX && _Broadcasting.TryGetValue(data.Hash, out tx)) { var payload = new TxPayload(tx); node.SendMessageAsync(payload); ListenerTrace.Info("Broadcasted " + data.Hash); } } } if (message.Message.Payload is RejectPayload) { var reject = (RejectPayload)message.Message.Payload; uint256 txId = reject.Hash; if (txId != null) { ListenerTrace.Info("Broadcasted transaction rejected (" + reject.Code + ") " + txId); if (reject.Code != RejectCode.DUPLICATE) { Configuration.GetRejectTable().Create(txId.ToString(), reject); } Transaction tx; _Broadcasting.TryRemove(txId, out tx); } } }
private void ProcessTxPayload(TxPayload transactionPayload) { var transaction = transactionPayload.Object as Transaction; MemPoolService.OnTransactionReceived(new SmartTransaction(transaction, Height.Unknown)); }