-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathAnnouncerProcessor.cs
123 lines (103 loc) · 4.56 KB
/
AnnouncerProcessor.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MithrilShards.Chain.Bitcoin.Consensus;
using MithrilShards.Chain.Bitcoin.Network;
using MithrilShards.Chain.Bitcoin.Protocol.Messages;
using MithrilShards.Core.EventBus;
using MithrilShards.Core.Network.PeerBehaviorManager;
using MithrilShards.Core.Network.Protocol.Processors;
namespace MithrilShards.Chain.Bitcoin.Protocol.Processors;
/// <summary>
/// Feed peers with data they require.
/// </summary>
/// <seealso cref="BaseProcessor" />
public partial class AnnouncerProcessor : BaseProcessor,
INetworkMessageHandler<SendHeadersMessage>,
INetworkMessageHandler<SendCmpctMessage>
{
readonly IDateTimeProvider _dateTimeProvider;
private readonly IInitialBlockDownloadTracker _ibdState;
readonly ILocalServiceProvider _localServiceProvider;
readonly IChainState _chainState;
readonly BitcoinSettings _settings;
public override bool Enabled => false; // Work in progress, actually disabled
public AnnouncerProcessor(ILogger<DataFeederProcessor> logger,
IEventBus eventBus,
IDateTimeProvider dateTimeProvider,
IPeerBehaviorManager peerBehaviorManager,
IInitialBlockDownloadTracker ibdState,
ILocalServiceProvider localServiceProvider,
IChainState chainState,
IOptions<BitcoinSettings> options)
: base(logger, eventBus, peerBehaviorManager, isHandshakeAware: true, receiveMessagesOnlyIfHandshaked: true)
{
_dateTimeProvider = dateTimeProvider;
_ibdState = ibdState;
_localServiceProvider = localServiceProvider;
_chainState = chainState;
_settings = options.Value;
}
protected override ValueTask OnPeerAttachedAsync()
{
// TODO: will attach to events needed to know when there is something useful to send to peers
// e.g. RegisterLifeTimeEventHandler<BlockHeaderValidationSucceeded>(OnBlockHeaderValidationSucceededAsync);
return base.OnPeerAttachedAsync();
}
/// <summary>
/// When the peer handshake, sends <see cref="SendCmpctMessage" /> and <see cref="SendHeadersMessage" /> if the
/// negotiated protocol allow that and update peer status based on its version message.
/// </summary>
/// <returns></returns>
protected override async ValueTask OnPeerHandshakedAsync()
{
HandshakeProcessor.HandshakeProcessorStatus handshakeStatus = PeerContext.Features.Get<HandshakeProcessor.HandshakeProcessorStatus>()!;
VersionMessage peerVersion = handshakeStatus.PeerVersion!;
logger.LogDebug("Peer {PeerId} handshake completed. Peer version: {PeerVersion}", PeerContext.PeerId, peerVersion);
await SendMessageAsync(minVersion: KnownVersion.V70012, new SendHeadersMessage()).ConfigureAwait(false);
}
/// <summary>
/// The other peer prefer to be announced about new block using headers
/// </summary>
ValueTask<bool> INetworkMessageHandler<SendHeadersMessage>.ProcessMessageAsync(SendHeadersMessage message, CancellationToken cancellation)
{
_status.AnnounceNewBlockUsingSendHeaders = true;
return new ValueTask<bool>(true);
}
/// <summary>
/// The other peer prefer to receive blocks using cmpct messages.
/// </summary>
ValueTask<bool> INetworkMessageHandler<SendCmpctMessage>.ProcessMessageAsync(SendCmpctMessage message, CancellationToken cancellation)
{
if (message.Version == 1 || (_localServiceProvider.HasServices(NodeServices.Witness) && message.Version == 2))
{
if (!_status.ProvidesHeaderAndIDs)
{
_status.ProvidesHeaderAndIDs = true;
_status.WantsCompactWitness = message.Version == 2;
}
// ignore later version announces
if (_status.WantsCompactWitness = message.Version == 2)
{
_status.AnnounceUsingCompactBlock = message.AnnounceUsingCompactBlock;
}
if (!_status.SupportsDesiredCompactVersion)
{
if (_localServiceProvider.HasServices(NodeServices.Witness))
{
_status.SupportsDesiredCompactVersion = message.Version == 2;
}
else
{
_status.SupportsDesiredCompactVersion = message.Version == 1;
}
}
}
else
{
logger.LogDebug("Ignoring sendcmpct message because its version is unknown.");
}
return new ValueTask<bool>(true);
}
}