/// <summary> /// Broadcast a transaction, if the same template behavior as been used for other nodes, they will also broadcast /// </summary> /// <param name="transaction">The transaction to broadcast</param> /// <returns>The cause of the rejection or null</returns> public Task <RejectPayload> BroadcastTransactionAsync(Transaction transaction) { AssertGroupAffected(); var hub = BroadcastHub.GetBroadcastHub(_Group.NodeConnectionParameters); if (hub == null) { throw new InvalidOperationException("No broadcast hub detected in the group"); } return(hub.BroadcastTransactionAsync(transaction)); }
protected override void AttachCore() { _Tracker = AttachedNode.Behaviors.Find <TrackerBehavior>(); if (_Tracker != null) { AttachedNode.Disconnected += AttachedNode_Disconnected; AttachedNode.StateChanged += AttachedNode_StateChanged; } _Broadcast = BroadcastHub.GetBroadcastHub(AttachedNode); if (_Broadcast != null) { _Broadcast.TransactionBroadcasted += _Broadcast_TransactionBroadcasted; _Broadcast.TransactionRejected += _Broadcast_TransactionRejected; } }
protected override void AttachCore() { #pragma warning disable CS0612 // Type or member is obsolete _Tracker = AttachedNode.Behaviors.Find <TrackerBehavior>(); #pragma warning restore CS0612 // Type or member is obsolete if (_Tracker != null) { AttachedNode.Disconnected += AttachedNode_Disconnected; AttachedNode.StateChanged += AttachedNode_StateChanged; } _Broadcast = BroadcastHub.GetBroadcastHub(AttachedNode); if (_Broadcast != null) { _Broadcast.TransactionBroadcasted += _Broadcast_TransactionBroadcasted; _Broadcast.TransactionRejected += _Broadcast_TransactionRejected; } }
public void ShouldSyncBlockChainAgainstLocal() { var network = new TestNetwork(); network.AddSeed(new NetworkAddress(new IPEndPoint(IPAddress.Parse("192.168.2.101"), 9999))); var p = new TestTransactionPool(); p.Add("t1", 1); p.Add("t2", 0); p.Spend("t2", "t1", 0); p.Render(); var genesisBlock = new TestBlock(p.TakeOut("t1").Value); var block1 = new TestBlock(p.TakeOut("t2").Value); block1.Parent = genesisBlock; genesisBlock.Render(); block1.Render(); WithBlockChains(1, genesisBlock.Value.Key, blockChains => { // blockChains[0].HandleNewBlock(genesisBlock.Value.Value); // blockChains[0].HandleNewBlock(block1.Value.Value); AutoResetEvent waitForConnection = new AutoResetEvent(false); bool connected = false; blockChains[0].OnAddedToStore += transaction => { Trace.Information("-- Transaction Received (node server)"); // actionReceiver(); }; AddressManager addressManager = new AddressManager(); addressManager.PeersToFind = 1; NodeConnectionParameters nodesGroupParameters = new NodeConnectionParameters(); // nodesGroupParameters.AddressFrom = servers[1].ExternalEndpoint; nodesGroupParameters.TemplateBehaviors.Add(new AddressManagerBehavior(addressManager)); nodesGroupParameters.TemplateBehaviors.Add(new ChainBehavior(blockChains[0])); nodesGroupParameters.TemplateBehaviors.Add(new BroadcastHubBehavior()); nodesGroupParameters.TemplateBehaviors.Add(new SPVBehavior(blockChains[0], BroadcastHub.GetBroadcastHub(nodesGroupParameters.TemplateBehaviors))); NodesGroup nodesGroup = new NodesGroup(network, nodesGroupParameters); nodesGroup.AllowSameGroup = true; nodesGroup.MaximumNodeConnection = 1; nodesGroup.ConnectedNodes.Added += (object sender, NodeEventArgs e) => { Trace.Information("-- Node added to node group"); connected = true; waitForConnection.Set(); }; nodesGroup.Connect(); Assert.True(waitForConnection.WaitOne(10000)); //TODO: use reset events instead of sleep Assert.True(connected); //TODO Thread.Sleep(40000); // actionSender(BroadcastHub.GetBroadcastHub(nodesGroup.NodeConnectionParameters)); Trace.Information("-- Done"); }); }
private void BroadcastTransaction(Action <BroadcastHub> actionSender, Action actionReceiver) { WithServerSet(2, servers => { WithBlockChains(2, null, blockChains => { AutoResetEvent waitForConnection = new AutoResetEvent(false); bool connected = false; servers.SeedServerIndex = 0; AddressManager serverAddressManager = new AddressManager(); serverAddressManager.Add( new NetworkAddress(servers[0].ExternalEndpoint), servers[0].ExternalEndpoint.Address ); serverAddressManager.Connected(new NetworkAddress(servers[0].ExternalEndpoint)); NodeConnectionParameters serverParameters = new NodeConnectionParameters(); serverParameters.TemplateBehaviors.Add(new AddressManagerBehavior(serverAddressManager)); serverParameters.TemplateBehaviors.Add(new BroadcastHubBehavior()); serverParameters.TemplateBehaviors.Add(new SPVBehavior(blockChains[0], BroadcastHub.GetBroadcastHub(serverParameters.TemplateBehaviors))); blockChains[0].OnAddedToMempool += transaction => { Trace.Information("-- Transaction Received (node server)"); actionReceiver(); }; servers[0].InboundNodeConnectionParameters = serverParameters; #region NodeGroup AddressManager addressManager = new AddressManager(); addressManager.PeersToFind = 1; NodeConnectionParameters nodesGroupParameters = new NodeConnectionParameters(); nodesGroupParameters.AddressFrom = servers[1].ExternalEndpoint; nodesGroupParameters.TemplateBehaviors.Add(new AddressManagerBehavior(addressManager)); nodesGroupParameters.TemplateBehaviors.Add(new BroadcastHubBehavior()); nodesGroupParameters.TemplateBehaviors.Add(new SPVBehavior(blockChains[1], BroadcastHub.GetBroadcastHub(nodesGroupParameters.TemplateBehaviors))); blockChains[1].OnAddedToMempool += transaction => { Trace.Information("-- Transaction Received (node group)"); }; NodesGroup nodesGroup = new NodesGroup(servers.Network, nodesGroupParameters); nodesGroup.AllowSameGroup = true; nodesGroup.MaximumNodeConnection = 1; nodesGroup.ConnectedNodes.Added += (object sender, NodeEventArgs e) => { Trace.Information("-- Node added to node group"); connected = true; waitForConnection.Set(); }; nodesGroup.Connect(); #endregion Assert.True(waitForConnection.WaitOne(10000)); //TODO: use reset events instead of sleep Assert.True(connected); actionSender(BroadcastHub.GetBroadcastHub(nodesGroup.NodeConnectionParameters)); Trace.Information("-- Done"); }); }); }
public void CanBroadcastTransaction() { using (NodeServerTester servers = new NodeServerTester(Network.TestNet)) { var notifiedTransactions = new List <WalletTransaction>(); var chainBuilder = new BlockchainBuilder(); SetupSPVBehavior(servers, chainBuilder); var tx = new Transaction(); Wallet wallet = new Wallet(new WalletCreation() { Network = Network.TestNet, RootKeys = new[] { new ExtKey().Neuter() }, UseP2SH = false }, keyPoolSize: 11); NodesGroup connected = CreateGroup(servers, 2); wallet.Configure(connected); wallet.Connect(); AutoResetEvent evt = new AutoResetEvent(false); bool passed = false; bool rejected = false; var broadcasting = wallet.BroadcastTransactionAsync(tx); wallet.TransactionBroadcasted += (t) => { passed = true; evt.Set(); }; wallet.TransactionRejected += (t, r) => { rejected = true; evt.Set(); }; BroadcastHub hub = BroadcastHub.GetBroadcastHub(connected.NodeConnectionParameters); BroadcastHubBehavior behavior = null; while (behavior == null || behavior.AttachedNode.State != NodeState.HandShaked) { behavior = connected.ConnectedNodes.Select(n => n.Behaviors.Find <BroadcastHubBehavior>()).FirstOrDefault(); Thread.Sleep(1); } if (broadcasting.Status != TaskStatus.RanToCompletion) { Assert.Equal(1, behavior.Broadcasts.Count()); Assert.Equal(1, hub.BroadcastingTransactions.Count()); } Assert.True(evt.WaitOne(20000)); Assert.True(broadcasting.Status == TaskStatus.RanToCompletion); Assert.True(passed); evt.Reset(); Assert.Equal(0, behavior.Broadcasts.Count()); Assert.Equal(0, hub.BroadcastingTransactions.Count()); Assert.Null(broadcasting.Result); broadcasting = wallet.BroadcastTransactionAsync(tx); if (broadcasting.Status != TaskStatus.RanToCompletion) { Assert.Equal(1, behavior.Broadcasts.Count()); } Assert.True(evt.WaitOne(20000)); Assert.True(rejected); Assert.Equal(0, behavior.Broadcasts.Count()); Assert.Equal(0, hub.BroadcastingTransactions.Count()); Assert.NotNull(broadcasting.Result); } }
//[Trait("UnitTest", "UnitTest")] public void CanBroadcastTransaction() { using (NodeServerTester servers = new NodeServerTester()) { var notifiedTransactions = new List <WalletTransaction>(); var chainBuilder = new BlockchainBuilder(); SetupSPVBehavior(servers, chainBuilder); var tx = new Transaction(); Wallet wallet = new Wallet(new WalletCreation() { Network = servers.Network, RootKeys = new[] { new ExtKey().Neuter() }, UseP2SH = false }, keyPoolSize: 11); NodesGroup connected = CreateGroup(servers, 2); wallet.Configure(connected); wallet.Connect(); AutoResetEvent evt = new AutoResetEvent(false); bool passed = false; bool rejected = false; BroadcastHub hub = BroadcastHub.GetBroadcastHub(wallet.Group.NodeConnectionParameters); hub.ManualBroadcast = true; var broadcasting = wallet.BroadcastTransactionAsync(tx); wallet.TransactionBroadcasted += (t) => { passed = true; evt.Set(); }; wallet.TransactionRejected += (t, r) => { rejected = true; evt.Set(); }; while (connected.ConnectedNodes.Count != 2 && connected.ConnectedNodes.All(n => n.State == NodeState.HandShaked)) { Thread.Sleep(10); } var behaviors = connected.ConnectedNodes.Select(n => n.Behaviors.Find <BroadcastHubBehavior>()).ToArray(); TestUtils.Eventually(() => behaviors.All(b => b.Broadcasts.Count() == 1)); Assert.Equal(1, hub.BroadcastingTransactions.Count()); hub.BroadcastTransactions(); Assert.True(evt.WaitOne(20000)); Assert.True(broadcasting.Wait(2000)); Assert.True(passed); evt.Reset(); TestUtils.Eventually(() => behaviors.All(b => b.Broadcasts.Count() == 0)); Assert.Equal(0, hub.BroadcastingTransactions.Count()); Assert.Null(broadcasting.Result); broadcasting = wallet.BroadcastTransactionAsync(tx); TestUtils.Eventually(() => behaviors.All(b => b.Broadcasts.Count() == 1)); hub.BroadcastTransactions(); Assert.True(evt.WaitOne(20000)); Assert.True(broadcasting.Wait(2000)); Assert.True(rejected); TestUtils.Eventually(() => behaviors.All(b => b.Broadcasts.Count() == 0)); Assert.Equal(0, hub.BroadcastingTransactions.Count()); Assert.NotNull(broadcasting.Result); } }