Skip to content

Commit 0289121

Browse files
authored
Adding UI for coldstaking (#116)
* Create am index per wallet file * Refactor some wallet compnents * Moving folders around * Refactor staking projects * Adding UI for coldstaking * Fix bug whre only one index was discovering the cold stake output in P2WSH and P2SH * Implement broadcast all unconfirmed in wallet * Fix tests * Only show coldstaking if its activated
1 parent 45b0d9c commit 0289121

151 files changed

Lines changed: 1558 additions & 737 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/Blockcore/Base/BaseFeature.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ public override async Task InitializeAsync()
215215
connectionParameters.TemplateBehaviors.Add(new PeerBanningBehavior(this.loggerFactory, this.peerBanning, this.nodeSettings));
216216
connectionParameters.TemplateBehaviors.Add(new BlockPullerBehavior(this.blockPuller, this.initialBlockDownloadState, this.dateTimeProvider, this.loggerFactory));
217217
connectionParameters.TemplateBehaviors.Add(new ConnectionManagerBehavior(this.connectionManager, this.loggerFactory));
218-
connectionParameters.TemplateBehaviors.Add(new BroadcasterBehavior(this.broadcasterManager, this.loggerFactory));
218+
connectionParameters.TemplateBehaviors.Add(new BroadcasterBehavior(this.network, this.broadcasterManager, this.loggerFactory));
219219

220220
this.StartAddressManager(connectionParameters);
221221

src/Blockcore/Base/Deployments/NodeDeployments.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,16 @@ public virtual DeploymentFlags GetFlags(ChainedHeader block)
3434
return flags;
3535
}
3636
}
37+
38+
public virtual DeploymentFlags GetFlags()
39+
{
40+
lock (this.BIP9)
41+
{
42+
ChainedHeader chainedHeader = this.chainIndexer.Tip;
43+
ThresholdState[] states = this.BIP9.GetStates(chainedHeader.Previous);
44+
var flags = new DeploymentFlags(chainedHeader, states, this.network.Consensus, this.chainIndexer);
45+
return flags;
46+
}
47+
}
3748
}
38-
}
49+
}

src/Blockcore/Connection/Broadcasting/BroadcastTransactionStateChanedEntry.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ public class BroadcastTransactionStateChanedEntry
88

99
public TransactionBroadcastState TransactionBroadcastState { get; set; }
1010

11-
public string ErrorMessage => (this.MempoolError == null) ? string.Empty : $"Failed: {this.ErrorMessage}";
11+
public string ErrorMessage { get; private set; }
1212

13-
public string MempoolError { get; set; }
13+
public bool CanRespondToGetData { get; set; }
1414

15-
public BroadcastTransactionStateChanedEntry(NBitcoin.Transaction transaction, TransactionBroadcastState transactionBroadcastState, string mempoolError)
15+
public BroadcastTransactionStateChanedEntry(NBitcoin.Transaction transaction, TransactionBroadcastState transactionBroadcastState, string errorMessage)
1616
{
1717
this.Transaction = transaction ?? throw new ArgumentNullException(nameof(transaction));
1818
this.TransactionBroadcastState = transactionBroadcastState;
19-
this.MempoolError = mempoolError;
19+
this.ErrorMessage = (errorMessage == null) ? string.Empty : errorMessage;
2020
}
2121
}
2222
}

src/Blockcore/Connection/Broadcasting/BroadcasterBehavior.cs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,35 +8,40 @@
88
using Blockcore.P2P.Protocol.Behaviors;
99
using Blockcore.P2P.Protocol.Payloads;
1010
using Microsoft.Extensions.Logging;
11+
using NBitcoin;
1112

1213
namespace Blockcore.Connection.Broadcasting
1314
{
1415
public class BroadcasterBehavior : NetworkPeerBehavior
1516
{
17+
private readonly Network network;
1618
private readonly IBroadcasterManager broadcasterManager;
1719

1820
/// <summary>Instance logger for the memory pool component.</summary>
1921
private readonly ILogger logger;
2022

2123
public BroadcasterBehavior(
24+
Network network,
2225
IBroadcasterManager broadcasterManager,
2326
ILogger logger)
2427
{
2528
this.logger = logger;
29+
this.network = network;
2630
this.broadcasterManager = broadcasterManager;
2731
}
2832

2933
public BroadcasterBehavior(
34+
Network network,
3035
IBroadcasterManager broadcasterManager,
3136
ILoggerFactory loggerFactory)
32-
: this(broadcasterManager, loggerFactory.CreateLogger(typeof(BroadcasterBehavior).FullName))
37+
: this(network, broadcasterManager, loggerFactory.CreateLogger(typeof(BroadcasterBehavior).FullName))
3338
{
3439
}
3540

3641
/// <inheritdoc />
3742
public override object Clone()
3843
{
39-
return new BroadcasterBehavior(this.broadcasterManager, this.logger);
44+
return new BroadcasterBehavior(this.network, this.broadcasterManager, this.logger);
4045
}
4146

4247
/// <summary>
@@ -105,10 +110,15 @@ protected async Task ProcessGetDataPayloadAsync(INetworkPeer peer, GetDataPayloa
105110
foreach (InventoryVector inv in getDataPayload.Inventory.Where(x => x.Type == InventoryType.MSG_TX))
106111
{
107112
BroadcastTransactionStateChanedEntry txEntry = this.broadcasterManager.GetTransaction(inv.Hash);
108-
if ((txEntry != null) && (txEntry.TransactionBroadcastState != TransactionBroadcastState.CantBroadcast))
113+
if ((txEntry != null) && (txEntry.TransactionBroadcastState != TransactionBroadcastState.FailedBroadcast))
109114
{
110-
await peer.SendMessageAsync(new TxPayload(txEntry.Transaction)).ConfigureAwait(false);
111-
if (txEntry.TransactionBroadcastState == TransactionBroadcastState.ToBroadcast)
115+
if (txEntry.CanRespondToGetData && peer.IsConnected)
116+
{
117+
this.logger.LogDebug("Sending transaction '{0}' to peer '{1}'.", inv.Hash, peer.RemoteSocketEndpoint);
118+
await peer.SendMessageAsync(new TxPayload(txEntry.Transaction.WithOptions(peer.SupportedTransactionOptions, this.network.Consensus.ConsensusFactory))).ConfigureAwait(false);
119+
}
120+
121+
if (txEntry.TransactionBroadcastState == TransactionBroadcastState.ReadyToBroadcast)
112122
{
113123
this.broadcasterManager.AddOrUpdate(txEntry.Transaction, TransactionBroadcastState.Broadcasted);
114124
}

src/Blockcore/Connection/Broadcasting/BroadcasterManager.cs

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,41 +18,44 @@ public class BroadcasterManager : IBroadcasterManager
1818
private readonly ISignals signals;
1919
private readonly IEnumerable<IBroadcastCheck> broadcastChecks;
2020

21+
private Dictionary<uint256, BroadcastTransactionStateChanedEntry> Broadcasts { get; }
22+
23+
public bool CanRespondToTrxGetData { get; set; }
24+
2125
public BroadcasterManager(IConnectionManager connectionManager, ISignals signals, IEnumerable<IBroadcastCheck> broadcastChecks)
2226
{
2327
Guard.NotNull(connectionManager, nameof(connectionManager));
2428

2529
this.connectionManager = connectionManager;
2630
this.signals = signals;
2731
this.broadcastChecks = broadcastChecks;
28-
this.Broadcasts = new ConcurrentHashSet<BroadcastTransactionStateChanedEntry>();
32+
this.Broadcasts = new Dictionary<uint256, BroadcastTransactionStateChanedEntry>();
33+
this.CanRespondToTrxGetData = true;
2934
}
3035

3136
public void OnTransactionStateChanged(BroadcastTransactionStateChanedEntry entry)
3237
{
3338
this.signals.Publish(new TransactionBroadcastEvent(this, entry));
3439
}
3540

36-
/// <summary>Transactions to broadcast.</summary>
37-
private ConcurrentHashSet<BroadcastTransactionStateChanedEntry> Broadcasts { get; }
38-
3941
/// <summary>Retrieves a transaction with provided hash from the collection of transactions to broadcast.</summary>
4042
/// <param name="transactionHash">Hash of the transaction to retrieve.</param>
4143
public BroadcastTransactionStateChanedEntry GetTransaction(uint256 transactionHash)
4244
{
43-
BroadcastTransactionStateChanedEntry txEntry = this.Broadcasts.FirstOrDefault(x => x.Transaction.GetHash() == transactionHash);
45+
BroadcastTransactionStateChanedEntry txEntry = this.Broadcasts.TryGet(transactionHash);
4446
return txEntry ?? null;
4547
}
4648

4749
/// <summary>Adds or updates a transaction from the collection of transactions to broadcast.</summary>
4850
public void AddOrUpdate(Transaction transaction, TransactionBroadcastState transactionBroadcastState, string errorMessage = null)
4951
{
50-
BroadcastTransactionStateChanedEntry broadcastEntry = this.Broadcasts.FirstOrDefault(x => x.Transaction.GetHash() == transaction.GetHash());
52+
uint256 trxHash = transaction.GetHash();
53+
BroadcastTransactionStateChanedEntry broadcastEntry = this.Broadcasts.TryGet(trxHash);
5154

5255
if (broadcastEntry == null)
5356
{
5457
broadcastEntry = new BroadcastTransactionStateChanedEntry(transaction, transactionBroadcastState, errorMessage);
55-
this.Broadcasts.Add(broadcastEntry);
58+
this.Broadcasts.Add(trxHash, broadcastEntry);
5659
this.OnTransactionStateChanged(broadcastEntry);
5760
}
5861
else if (broadcastEntry.TransactionBroadcastState != transactionBroadcastState)
@@ -77,30 +80,51 @@ public async Task BroadcastTransactionAsync(Transaction transaction)
7780

7881
if (!string.IsNullOrEmpty(error))
7982
{
80-
this.AddOrUpdate(transaction, TransactionBroadcastState.CantBroadcast, error);
83+
this.AddOrUpdate(transaction, TransactionBroadcastState.FailedBroadcast, error);
8184
return;
8285
}
8386
}
8487

85-
await this.PropagateTransactionToPeersAsync(transaction, this.connectionManager.ConnectedPeers.ToList()).ConfigureAwait(false);
88+
await this.PropagateTransactionToPeersAsync(transaction).ConfigureAwait(false);
89+
}
90+
91+
public async Task<bool> BroadcastTransactionAsync(uint256 trxHash)
92+
{
93+
if (this.Broadcasts.TryGetValue(trxHash, out BroadcastTransactionStateChanedEntry entry))
94+
{
95+
if (entry.TransactionBroadcastState == TransactionBroadcastState.ReadyToBroadcast ||
96+
entry.TransactionBroadcastState == TransactionBroadcastState.Broadcasted)
97+
{
98+
// broadacste
99+
await this.PropagateTransactionToPeersAsync(entry.Transaction).ConfigureAwait(false);
100+
101+
return true;
102+
}
103+
}
104+
105+
return false;
86106
}
87107

88108
/// <summary>
89109
/// Sends transaction to peers.
90110
/// </summary>
91111
/// <param name="transaction">Transaction that will be propagated.</param>
92-
/// <param name="peers">Peers to whom we will propagate the transaction.</param>
93-
protected async Task PropagateTransactionToPeersAsync(Transaction transaction, List<INetworkPeer> peers)
112+
protected async Task PropagateTransactionToPeersAsync(Transaction transaction)
94113
{
95-
this.AddOrUpdate(transaction, TransactionBroadcastState.ToBroadcast);
114+
this.AddOrUpdate(transaction, TransactionBroadcastState.ReadyToBroadcast);
96115

97116
var invPayload = new InvPayload(transaction);
98117

118+
List<INetworkPeer> peers = this.connectionManager.ConnectedPeers.ToList();
119+
99120
foreach (INetworkPeer peer in peers)
100121
{
101122
try
102123
{
103-
await peer.SendMessageAsync(invPayload).ConfigureAwait(false);
124+
if (peer.IsConnected)
125+
{
126+
await peer.SendMessageAsync(invPayload).ConfigureAwait(false);
127+
}
104128
}
105129
catch (OperationCanceledException)
106130
{

src/Blockcore/Connection/Broadcasting/TransactionBroadcastState.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
{
33
public enum TransactionBroadcastState
44
{
5-
CantBroadcast,
6-
ToBroadcast,
5+
FailedBroadcast,
6+
ReadyToBroadcast,
77
Broadcasted,
88
Propagated
99
}
10-
}
10+
}

src/Blockcore/Interfaces/IBroadcasterManager.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Threading.Tasks;
34
using Blockcore.Connection.Broadcasting;
45
using NBitcoin;
@@ -15,10 +16,14 @@ public interface IBroadcastCheck
1516

1617
public interface IBroadcasterManager
1718
{
19+
bool CanRespondToTrxGetData { get; set; }
20+
1821
Task BroadcastTransactionAsync(Transaction transaction);
1922

2023
BroadcastTransactionStateChanedEntry GetTransaction(uint256 transactionHash);
2124

2225
void AddOrUpdate(Transaction transaction, TransactionBroadcastState transactionBroadcastState, string errorMessage = null);
26+
27+
Task<bool> BroadcastTransactionAsync(uint256 trxHash);
2328
}
2429
}

src/External/NBitcoin.Tests/NetworkTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ public void BitcoinMainnetIsInitializedCorrectly()
144144
Assert.Equal(Utils.UnixTimeToDateTime(1510704000), this.networkMain.Consensus.BIP9Deployments[BitcoinBIP9Deployments.Segwit].Timeout);
145145
Assert.Equal(0, this.networkMain.Consensus.CoinType);
146146
Assert.False(this.networkMain.Consensus.IsProofOfStake);
147-
Assert.Equal(new uint256("0x0000000000000000000f1c54590ee18d15ec70e68c8cd4cfbadb1b4f11697eee"), this.networkMain.Consensus.DefaultAssumeValid);
147+
Assert.Equal(new uint256("0x0000000000000000000304dece599f1d046f5c606deec3d1d49eb24b3231b4a3"), this.networkMain.Consensus.DefaultAssumeValid);
148148
Assert.Equal(100, this.networkMain.Consensus.CoinbaseMaturity);
149149
Assert.Equal(0, this.networkMain.Consensus.PremineReward);
150150
Assert.Equal(0, this.networkMain.Consensus.PremineHeight);
Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
11
@page "/peers"
22

33
@inject Blockcore.Connection.IConnectionManager ConnectionManager
4+
@inject NavigationManager NavigationManager
45

56
<h2>Connected peers</h2>
67

78
<p>Information about connected peers.</p>
89

910
@{
11+
<div class="input-group mb-3">
12+
<button class="btn btn-info" @onclick="NavigateToPeernodes">Add nodes</button>
13+
</div>
14+
<hr />
1015
<table class="table">
1116
<thead>
1217
<tr>
1318
<th>Ip</th>
1419
<th>Inbound</th>
1520
<th>Agent</th>
16-
<th>Time Offset</th>
21+
<th>Version</th>
1722
</tr>
1823
</thead>
1924
<tbody>
@@ -23,9 +28,17 @@
2328
<td>@peer.RemoteSocketEndpoint.ToString()</td>
2429
<td>@peer.Inbound</td>
2530
<td>@peer.PeerVersion?.UserAgent</td>
26-
<td>@peer.TimeOffset.Value</td>
31+
<td>@peer.PeerVersion?.Version</td>
2732
</tr>
2833
}
2934
</tbody>
3035
</table>
36+
}
37+
38+
@code
39+
{
40+
private void NavigateToPeernodes()
41+
{
42+
NavigationManager.NavigateTo("peers-nodes");
43+
}
3144
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
@page "/peers-nodes"
2+
3+
@using Blockcore.Utilities.Extensions
4+
5+
@inject Blockcore.Connection.IConnectionManager ConnectionManager
6+
7+
<h2>Connected peers</h2>
8+
9+
<p>Information about connected peers.</p>
10+
11+
@{
12+
<div class="input-group mb-3">
13+
<div class="input-group-prepend">
14+
<span class="input-group-text" id="basic-addon1">Node ip:</span>
15+
</div>
16+
<input @bind="NodeIp" type="text" class="form-control" placeholder="node ip" />
17+
<div class="input-group-append">
18+
<span class="input-group-text">add</span>
19+
</div>
20+
</div>
21+
22+
<div class="input-group mb-3">
23+
<button class="btn btn-info" @onclick="Addnode">Add node</button>
24+
</div>
25+
26+
<div class="input-group mb-3">
27+
<div class="alert-warning">@Alert</div>
28+
</div>
29+
}
30+
31+
@code
32+
{
33+
private string NodeIp { get; set; }
34+
35+
string Alert { get; set; }
36+
37+
private void Addnode()
38+
{
39+
var endpoint = this.NodeIp.ToIPEndPoint(this.ConnectionManager.Network.DefaultPort);
40+
41+
this.ConnectionManager.AddNodeAddress(endpoint);
42+
43+
this.Alert = $"node {endpoint} added";
44+
}
45+
}

0 commit comments

Comments
 (0)