Skip to content

Commit 9057f2a

Browse files
Merge pull request #121 from pingpongsneak/master
RC2
2 parents 714a9dc + ffe9b17 commit 9057f2a

22 files changed

+370
-234
lines changed

core/Controllers/MembershipController.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public async Task<IActionResult> GetPeerAsync()
4848
HttpsPort = peer.HttpsPort.FromBytes(),
4949
TcpPort = peer.TcpPort.FromBytes(),
5050
WsPort = peer.WsPort.FromBytes(),
51+
DsPort = peer.DsPort.FromBytes(),
5152
Name = peer.Name.FromBytes(),
5253
PublicKey = peer.PublicKey.ByteToHex(),
5354
Version = peer.Version.FromBytes()
@@ -81,6 +82,7 @@ public async Task<IActionResult> GetPeersAsync()
8182
HttpsPort = peer.HttpsPort.FromBytes(),
8283
TcpPort = peer.TcpPort.FromBytes(),
8384
WsPort = peer.WsPort.FromBytes(),
85+
DsPort = peer.DsPort.FromBytes(),
8486
Name = peer.Name.FromBytes(),
8587
PublicKey = peer.PublicKey.ByteToHex(),
8688
Version = peer.Version.FromBytes()

core/Cryptography/Crypto.cs

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@ public interface ICrypto
2222
Task<Models.KeyPair> GetOrUpsertKeyNameAsync(string keyName);
2323
Task<byte[]> GetPublicKeyAsync(string keyName);
2424
Task<SignatureResponse> SignAsync(string keyName, byte[] message);
25+
byte[] Sign(byte[] privateKey, byte[] message);
2526
bool VerifySignature(byte[] signature, byte[] message);
26-
bool VerifySignature(VerifySignatureManualRequest verifySignatureManualRequest);
27+
bool VerifySignature(byte[] publicKey, byte[] message, byte[] signature);
2728
byte[] GetCalculateVrfSignature(ECPrivateKey ecPrivateKey, byte[] msg);
2829
byte[] GetVerifyVrfSignature(ECPublicKey ecPublicKey, byte[] msg, byte[] sig);
2930
// byte[] EncryptChaCha20Poly1305(byte[] data, byte[] key, byte[] associatedData, out byte[] tag, out byte[] nonce);
@@ -131,6 +132,28 @@ public async Task<SignatureResponse> SignAsync(string keyName, byte[] message)
131132
return signatureResponse;
132133
}
133134

135+
/// <summary>
136+
///
137+
/// </summary>
138+
/// <param name="privateKey"></param>
139+
/// <param name="message"></param>
140+
/// <returns></returns>
141+
public byte[] Sign(byte[] privateKey, byte[] message)
142+
{
143+
Guard.Argument(privateKey, nameof(privateKey)).NotNull();
144+
Guard.Argument(message, nameof(message)).NotNull();
145+
try
146+
{
147+
return Curve.calculateSignature(Curve.decodePrivatePoint(privateKey), message);
148+
}
149+
catch (Exception ex)
150+
{
151+
_logger.Here().Error(ex, "Unable to sign the message");
152+
}
153+
154+
return null;
155+
}
156+
134157
/// <summary>
135158
/// </summary>
136159
/// <param name="signature"></param>
@@ -155,22 +178,21 @@ public bool VerifySignature(byte[] signature, byte[] message)
155178
}
156179

157180
/// <summary>
181+
///
158182
/// </summary>
159-
/// <param name="verifySignatureManualRequest"></param>
183+
/// <param name="publicKey"></param>
184+
/// <param name="message"></param>
185+
/// <param name="signature"></param>
160186
/// <returns></returns>
161-
public bool VerifySignature(VerifySignatureManualRequest verifySignatureManualRequest)
187+
public bool VerifySignature(byte[] publicKey, byte[] message, byte[] signature)
162188
{
163-
Guard.Argument(verifySignatureManualRequest, nameof(verifySignatureManualRequest)).NotNull();
164-
Guard.Argument(verifySignatureManualRequest.Signature, nameof(verifySignatureManualRequest.Signature))
165-
.NotNull();
166-
Guard.Argument(verifySignatureManualRequest.PublicKey, nameof(verifySignatureManualRequest.PublicKey))
167-
.NotNull();
168-
Guard.Argument(verifySignatureManualRequest.Message, nameof(verifySignatureManualRequest.Message)).NotNull();
189+
Guard.Argument(publicKey, nameof(publicKey)).NotNull();
190+
Guard.Argument(message, nameof(message)).NotNull();
191+
Guard.Argument(signature, nameof(signature)).NotNull();
169192
var verified = false;
170193
try
171194
{
172-
verified = Curve.verifySignature(Curve.decodePoint(verifySignatureManualRequest.PublicKey, 0),
173-
verifySignatureManualRequest.Message, verifySignatureManualRequest.Signature);
195+
verified = Curve.verifySignature(Curve.decodePoint(publicKey, 0), message, signature);
174196
}
175197
catch (Exception ex)
176198
{

core/Extensions/AppExtensions.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ public static ContainerBuilder AddCypherSystemCore(this ContainerBuilder builder
4747
builder.Register(c =>
4848
{
4949
var remoteNodes = configuration.GetSection("Node:Network:SeedList").GetChildren().ToArray();
50-
var remotePublicKeys = configuration.GetSection("Node:Network:SeedListPublicKeys").GetChildren().ToArray();
5150
var node = new Node
5251
{
5352
EndPoint = new IPEndPoint(Util.GetIpAddress(), 0),
@@ -67,11 +66,11 @@ public static ContainerBuilder AddCypherSystemCore(this ContainerBuilder builder
6766
P2P =
6867
new P2P
6968
{
69+
DsPort = Convert.ToInt32(configuration["Node:Network:P2P:DsPort"]),
7070
TcpPort = Convert.ToInt32(configuration["Node:Network:P2P:TcpPort"]),
7171
WsPort = Convert.ToInt32(configuration["Node:Network:P2P:WsPort"])
7272
},
7373
SeedList = new List<string>(remoteNodes.Length),
74-
SeedListPublicKeys = new List<string>(remoteNodes.Length),
7574
X509Certificate =
7675
new Models.X509Certificate
7776
{
@@ -106,9 +105,7 @@ public static ContainerBuilder AddCypherSystemCore(this ContainerBuilder builder
106105
{
107106
var endpoint = Util.GetIpEndPoint(selection.item.Value);
108107
var endpointFromHost = Util.GetIpEndpointFromHostPort(endpoint.Address.ToString(), endpoint.Port);
109-
var publicKey = remotePublicKeys[selection.index].Value;
110108
node.Network.SeedList.Add($"{endpointFromHost.Address.ToString()}:{endpointFromHost.Port}");
111-
node.Network.SeedListPublicKeys.Add(publicKey);
112109
}
113110

114111
var cypherSystemCore = new CypherSystemCore(c.Resolve<IHostApplicationLifetime>(),

core/Ledger/Graph.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ public async Task<SafeguardBlocksResponse> GetSafeguardBlocksAsync(SafeguardBloc
236236
try
237237
{
238238
var hashChainRepository = _cypherSystemCore.UnitOfWork().HashChainRepository;
239-
var height = hashChainRepository.Height == 0 ? 0 : hashChainRepository.Height - (ulong)safeguardBlocksRequest.NumberOfBlocks;
239+
var height = hashChainRepository.Height <= (ulong)safeguardBlocksRequest.NumberOfBlocks ? hashChainRepository.Height : hashChainRepository.Height - (ulong)safeguardBlocksRequest.NumberOfBlocks;
240240
var blocks = await hashChainRepository.OrderByRangeAsync(x => x.Height, (int)height,
241241
safeguardBlocksRequest.NumberOfBlocks);
242242
if (blocks.Any()) return new SafeguardBlocksResponse(blocks, string.Empty);
@@ -474,7 +474,7 @@ private bool Save(BlockGraph blockGraph)
474474
Guard.Argument(blockGraph, nameof(blockGraph)).NotNull();
475475
try
476476
{
477-
if (_cypherSystemCore.Validator().VerifyBlockGraphSignatureNodeRound(blockGraph).Result != VerifyResult.Succeed)
477+
if (_cypherSystemCore.Validator().VerifyBlockGraphSignatureNodeRound(blockGraph) != VerifyResult.Succeed)
478478
{
479479
_logger.Error("Unable to verify block for {@Node} and round {@Round}", blockGraph.Block.Node,
480480
blockGraph.Block.Round);

core/Ledger/Sync.cs

Lines changed: 32 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using CypherNetwork.Models.Messages;
1313
using CypherNetwork.Network;
1414
using Dawn;
15+
using libsignal.util;
1516
using MessagePack;
1617
using Serilog;
1718
using Spectre.Console;
@@ -38,6 +39,8 @@ public class Sync : ISync, IDisposable
3839
private bool _disposed;
3940
private int _running;
4041

42+
private static readonly object LockOnSync = new();
43+
4144
/// <summary>
4245
/// </summary>
4346
/// <param name="cypherSystemCore"></param>
@@ -93,20 +96,25 @@ private async Task SynchronizeAsync()
9396
currentRetry++;
9497
}
9598

96-
foreach (var peer in _cypherSystemCore.PeerDiscovery().GetDiscoveryStore())
99+
var peers = _cypherSystemCore.PeerDiscovery().GetDiscoveryStore().Where(x => x.BlockCount > blockCount).ToArray();
100+
if (peers.Any() != true) return;
101+
peers.Shuffle();
102+
var maxBlockHeight = peers.Max(x => (long)x.BlockCount);
103+
var chunk = maxBlockHeight / peers.Length;
104+
_logger.Information("Peer count [{@PeerCount}]", peers.Length);
105+
_logger.Information("Network block height [{@MaxBlockHeight}]", maxBlockHeight);
106+
foreach (var peer in peers)
97107
{
98-
if (blockCount < peer.BlockCount)
108+
var skip = blockCount <= 6 ? blockCount : blockCount - 6; // +- Depth of blocks to compare.
109+
var take = (int)((int)blockCount + chunk);
110+
if (take > (int)maxBlockHeight)
99111
{
100-
var skip = blockCount == 0 ? 0 : blockCount - 6; // +- Depth of blocks to compare.
101-
var synchronized = await SynchronizeAsync(peer, (ulong)skip, (int)peer.BlockCount);
102-
if (!synchronized) continue;
103-
_logger.Information(
104-
"Successfully SYNCHRONIZED with node:{@NodeName} host:{@Host} version:{@Version}",
105-
peer.Name.FromBytes(), peer.IpAddress.FromBytes(), peer.Version.FromBytes());
106-
break;
112+
take = (int)(maxBlockHeight - (long)blockCount) + (int)blockCount;
107113
}
108-
114+
SynchronizeAsync(peer, skip, take).Wait();
109115
blockCount = _cypherSystemCore.UnitOfWork().HashChainRepository.Count;
116+
_logger.Information("Local block height ({@LocalHeight})", blockCount);
117+
if (blockCount == (ulong)maxBlockHeight) break;
110118
}
111119
}
112120
catch (Exception ex)
@@ -150,7 +158,7 @@ private async Task<bool> WaitForPeersAsync(int currentRetry, int retryCount)
150158
/// <param name="skip"></param>
151159
/// <param name="take"></param>
152160
/// <returns></returns>
153-
private async Task<bool> SynchronizeAsync(Peer peer, ulong skip, int take)
161+
private async Task SynchronizeAsync(Peer peer, ulong skip, int take)
154162
{
155163
Guard.Argument(peer, nameof(peer)).HasValue();
156164
Guard.Argument(skip, nameof(skip)).NotNegative();
@@ -160,15 +168,15 @@ private async Task<bool> SynchronizeAsync(Peer peer, ulong skip, int take)
160168
{
161169
var validator = _cypherSystemCore.Validator();
162170
var blocks = await FetchBlocksAsync(peer, skip, take);
163-
if (blocks?.Any() != true) return false;
171+
if (blocks?.Any() != true) return;
164172
if (skip == 0)
165173
{
166174
_logger.Warning("FIRST TIME BOOTSTRAPPING");
167175
}
168176
else
169177
{
170178
_logger.Information("CONTINUE BOOTSTRAPPING");
171-
_logger.Information("CHECKING [BLOCK HEIGHTS]");
179+
_logger.Information("CHECKING [BLOCK DUPLICATES]");
172180
var verifyNoDuplicateBlockHeights = validator.VerifyNoDuplicateBlockHeights(blocks);
173181
if (verifyNoDuplicateBlockHeights == VerifyResult.AlreadyExists)
174182
{
@@ -179,26 +187,26 @@ private async Task<bool> SynchronizeAsync(Peer peer, ulong skip, int take)
179187
ClientId = peer.ClientId,
180188
PeerState = PeerState.DupBlocks
181189
});
182-
_logger.Warning("Duplicate block heights [UNABLE TO VERIFY]");
183-
return false;
190+
_logger.Warning("DUPLICATE block height [UNABLE TO VERIFY]");
191+
return;
184192
}
185193

186194
_logger.Information("CHECKING [FORK RULE]");
187195
var forkRuleBlocks = await validator.VerifyForkRuleAsync(blocks.OrderBy(x => x.Height).ToArray());
188196
if (forkRuleBlocks.Length == 0)
189197
{
190-
_logger.Fatal("Fork rule check [UNABLE TO VERIFY]");
191-
return false;
198+
_logger.Fatal("FORK RULE CHECK [UNABLE TO VERIFY]");
199+
return;
192200
}
193201

194202
blocks = forkRuleBlocks.ToList();
195-
_logger.Information("Fork rule check [OK]");
203+
_logger.Information("FORK RULE CHECK [OK]");
196204
}
197205

198206
await AnsiConsole.Progress().AutoClear(false).Columns(new TaskDescriptionColumn(), new ProgressBarColumn(),
199207
new PercentageColumn(), new SpinnerColumn()).StartAsync(async ctx =>
200208
{
201-
var warpTask = ctx.AddTask($"SYNCHRONIZING [bold yellow]{blocks.Count}[/] Block(s)", false).IsIndeterminate();
209+
var warpTask = ctx.AddTask($"[bold green]SYNCHRONIZING[/] [bold yellow]{blocks.Count}[/] Block(s)", false).IsIndeterminate();
202210
warpTask.MaxValue(blocks.Count);
203211
warpTask.StartTask();
204212
warpTask.IsIndeterminate(false);
@@ -236,16 +244,7 @@ private async Task<bool> SynchronizeAsync(Peer peer, ulong skip, int take)
236244
catch (Exception ex)
237245
{
238246
_logger.Here().Error(ex, "SYNCHRONIZATION [FAILED]");
239-
return false;
240247
}
241-
finally
242-
{
243-
var blockCount = _cypherSystemCore.UnitOfWork().HashChainRepository.Count;
244-
_logger.Information("Local node block height set to ({@LocalHeight})", blockCount);
245-
if (blockCount == (ulong)take) isSynchronized = true;
246-
}
247-
248-
return isSynchronized;
249248
}
250249

251250
/// <summary>
@@ -259,23 +258,22 @@ private async Task<IReadOnlyList<Block>> FetchBlocksAsync(Peer peer, ulong skip,
259258
Guard.Argument(peer, nameof(peer)).HasValue();
260259
Guard.Argument(skip, nameof(skip)).NotNegative();
261260
Guard.Argument(take, nameof(take)).NotNegative();
262-
_logger.Information("Synchronizing with {@Host} ({@Skip})/({@Take})", peer.IpAddress.FromBytes(), skip, take);
263261
var iSkip = skip;
264262
try
265263
{
266-
_logger.Information("Fetching [{@Range}] block(s)", Math.Abs(take - (int)skip));
267264
const int maxBlocks = 10;
268-
var chunks = Enumerable.Repeat(maxBlocks, take / maxBlocks).ToList();
269-
if (take % maxBlocks != 0) chunks.Add(take % maxBlocks);
265+
var iTake = take - (int)skip;
266+
var chunks = Enumerable.Repeat(maxBlocks, iTake / maxBlocks).ToList();
267+
if (iTake % maxBlocks != 0) chunks.Add(iTake % maxBlocks);
270268

271269
// Show progress
272270
var blocks = await AnsiConsole.Progress().AutoClear(false).Columns(new TaskDescriptionColumn(),
273271
new ProgressBarColumn(), new PercentageColumn(), new SpinnerColumn())
274272
.StartAsync(async ctx =>
275273
{
276274
var blocks = new List<Block>();
277-
var warpTask = ctx.AddTask("DOWNLOADING", false).IsIndeterminate();
278-
warpTask.MaxValue(chunks.Count);
275+
var warpTask = ctx.AddTask($"[bold green]DOWNLOADING[/] [bold yellow]{Math.Abs(take - (int)skip)}[/] block(s) from [bold yellow]{peer.Name.FromBytes()}[/] v{peer.Version.FromBytes()}", false).IsIndeterminate();
276+
warpTask.MaxValue(take - (int)skip);
279277
warpTask.StartTask();
280278
warpTask.IsIndeterminate(false);
281279
while (!ctx.IsFinished)

core/Ledger/Validator.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ namespace CypherNetwork.Ledger;
3232
/// </summary>
3333
public interface IValidator
3434
{
35-
Task<VerifyResult> VerifyBlockGraphSignatureNodeRound(BlockGraph blockGraph);
35+
VerifyResult VerifyBlockGraphSignatureNodeRound(BlockGraph blockGraph);
3636
VerifyResult VerifyBulletProof(Transaction transaction);
3737
VerifyResult VerifyCoinbaseTransaction(Vout coinbase, ulong solution, decimal runningDistribution, ulong height);
3838
VerifyResult VerifySolution(byte[] vrfBytes, byte[] kernel, ulong solution);
@@ -88,15 +88,14 @@ public Validator(ICypherSystemCore cypherSystemCore, ILogger logger)
8888
public async Task<VerifyResult> VerifyBlockHashAsync(Block block)
8989
{
9090
Guard.Argument(block, nameof(block)).NotNull();
91-
using var hasher = Hasher.New();
9291
var hashChainRepository = _cypherSystemCore.UnitOfWork().HashChainRepository;
9392
var prevBlock = await hashChainRepository.GetAsync(x => new ValueTask<bool>(x.Height == hashChainRepository.Height));
9493
if (prevBlock is null)
9594
{
9695
_logger.Here().Error("No previous block available");
9796
return VerifyResult.UnableToVerify;
9897
}
99-
98+
using var hasher = Hasher.New();
10099
hasher.Update(prevBlock.Hash);
101100
hasher.Update(block.ToHash());
102101
var hash = hasher.Finalize();
@@ -129,14 +128,13 @@ public async Task<VerifyResult> VerifyMerkleAsync(Block block)
129128
/// </summary>
130129
/// <param name="blockGraph"></param>
131130
/// <returns></returns>
132-
public async Task<VerifyResult> VerifyBlockGraphSignatureNodeRound(BlockGraph blockGraph)
131+
public VerifyResult VerifyBlockGraphSignatureNodeRound(BlockGraph blockGraph)
133132
{
134133
Guard.Argument(blockGraph, nameof(blockGraph)).NotNull();
135134
try
136135
{
137136
if (!_cypherSystemCore.Crypto()
138-
.VerifySignature(new VerifySignatureManualRequest(blockGraph.Signature, blockGraph.PublicKey,
139-
blockGraph.ToHash())))
137+
.VerifySignature(blockGraph.PublicKey, blockGraph.ToHash(), blockGraph.Signature))
140138
{
141139
_logger.Error("Unable to verify the signature for block {@Round} from node {@Node}",
142140
blockGraph.Block.Round, blockGraph.Block.Node);

core/Models/LocalNode.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public record LocalNode
1616
public byte[] Name { get; init; }
1717
public byte[] TcpPort { get; init; }
1818
public byte[] WsPort { get; init; }
19+
public byte[] DsPort { get; init; }
1920
public byte[] HttpPort { get; init; }
2021
public byte[] HttpsPort { get; init; }
2122
public byte[] IpAddress { get; init; }

core/Models/Messages/ProtocolCommand.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ public enum ProtocolCommand : byte
99
Version = 0x01,
1010
GetPeer = 0x10,
1111
GetPeers = 0x11,
12-
UpdatePeers = 0x12,
1312
GetBlocks = 0x14,
1413
SaveBlock = 0x15,
1514
GetBlockHeight = 0x17,

core/Models/NetworkSetting.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,12 @@ public record Network
3737
public int HttpsPort { get; set; }
3838
public P2P P2P { get; set; }
3939
public IList<string> SeedList { get; set; }
40-
public IList<string> SeedListPublicKeys { get; set; }
4140
public string CertificateMode { get; set; }
4241
}
4342

4443
public record P2P
4544
{
45+
public int DsPort { get; set; }
4646
public int TcpPort { get; set; }
4747
public int WsPort { get; set; }
4848
}

core/Models/Peer.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,16 @@ public struct Peer : IComparable<Peer>
1717
[Key(3)] public ulong BlockCount { get; set; }
1818
[Key(4)] public ulong ClientId { get; init; }
1919
[Key(5)] public byte[] TcpPort { get; set; }
20-
[Key(6)] public byte[] WsPort { get; set; }
21-
[Key(7)] public byte[] Name { get; set; }
22-
[Key(8)] public byte[] PublicKey { get; set; }
23-
[Key(9)] public byte[] Version { get; set; }
20+
[Key(6)] public byte[] DsPort { get; set; }
21+
[Key(7)] public byte[] WsPort { get; set; }
22+
[Key(8)] public byte[] Name { get; set; }
23+
[Key(9)] public byte[] PublicKey { get; set; }
24+
[Key(10)] public byte[] Signature { get; set; }
25+
[Key(11)] public byte[] Version { get; set; }
26+
[Key(12)] public long Timestamp { get; set; }
2427
[IgnoreMember] public int Retries { get; set; }
25-
2628
/// <summary>
27-
/// </summary>
29+
/// </summary>s
2830
/// <param name="other"></param>
2931
/// <returns></returns>
3032
public int CompareTo(Peer other)

0 commit comments

Comments
 (0)