void RunTask(string name, Action act, bool commonThread) { new Task(() => { try { act(); } catch (Exception ex) { ListenerTrace.Error("Error during task : " + name, ex); LastException = ex; } }).Start(commonThread ? _Scheduler : TaskScheduler.Default); }
private void DeleteBroadcasted(DynamicTableEntity entity, uint256 hash) { try { BroadcastedTransaction unused; _BroadcastedTransactions.TryRemove(hash, out unused); entity.ETag = "*"; Configuration.GetBroadcastedTransactionsListenable().CloudTable.Execute(TableOperation.Delete(entity)); } catch (Exception ex) { StorageException storageEx = ex as StorageException; if (storageEx == null || storageEx.RequestInformation == null || storageEx.RequestInformation.HttpStatusCode != 404) { ListenerTrace.Error("Error while cleaning up broadcasted transaction " + hash, ex); } } }
public void Listen() { _Evt.Reset(); _Scheduler = new SingleThreadTaskScheduler(); ListenerTrace.Info("Connecting to node " + Configuration.Indexer.Node + "..."); _Node = _Configuration.Indexer.ConnectToNode(true); ListenerTrace.Info("Connected"); ListenerTrace.Info("Handshaking..."); _Node.VersionHandshake(); ListenerTrace.Info("Handshaked"); _Chain = new ConcurrentChain(_Configuration.Indexer.Network); ListenerTrace.Info("Fetching headers..."); _Node.SynchronizeChain(_Chain); ListenerTrace.Info("Headers fetched tip " + _Chain.Tip.Height); _Indexer = Configuration.Indexer.CreateIndexer(); ListenerTrace.Info("Indexing indexer chain..."); _Indexer.IndexChain(_Chain); _Node.MessageReceived += node_MessageReceived; _Wallets = _Configuration.Indexer.CreateIndexerClient().GetAllWalletRules(); ListenerTrace.Info("Connecting and handshaking for the sender node..."); _SenderNode = _Configuration.Indexer.ConnectToNode(false); _SenderNode.VersionHandshake(); _SenderNode.MessageReceived += _SenderNode_MessageReceived; ListenerTrace.Info("Sender node handshaked"); ListenerTrace.Info("Fetching transactions to broadcast..."); _Disposables.Add( Configuration .GetBroadcastedTransactionsListenable() .CreateConsumer() .EnsureExists() .OnMessage(evt => { uint256 hash = null; try { if (evt.Addition) { var tx = new BroadcastedTransaction(evt.AddedEntity); hash = tx.Transaction.GetHash(); var value = _BroadcastedTransactions.GetOrAdd(hash, tx); ListenerTrace.Info("Broadcasting " + hash); if (value == tx) //Was not present before { _SenderNode.SendMessage(new InvPayload(tx.Transaction)); } } } catch (Exception ex) { LastException = ex; ListenerTrace.Error("Error for new broadcasted transaction " + hash, ex); } finally { DeleteExpiredBroadcasted(evt, hash); } })); ListenerTrace.Info("Transactions to broadcast fetched"); ListenerTrace.Info("Fetching wallet rules..."); _Disposables.Add(Configuration .GetWalletRuleListenable() .CreateConsumer() .EnsureExists() .OnMessage(evt => { ListenerTrace.Info("New wallet rule"); RunTask("New wallet rule", () => { _Wallets.Add(new WalletRuleEntry(evt.AddedEntity, Configuration.Indexer.CreateIndexerClient())); }, true); })); ListenerTrace.Info("Wallet rules fetched"); var ping = new Timer(Ping, null, 0, 1000 * 60); _Disposables.Add(ping); }