Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions plugins/ApplicationLogs/ApplicationLogs.csproj
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Neo.ConsoleService\Neo.ConsoleService.csproj" />
<ProjectReference Include="..\RpcServer\RpcServer.csproj" AdditionalProperties="IncludeSettingsFileOutput=False">
Expand Down
16 changes: 9 additions & 7 deletions plugins/DBFTPlugin/Consensus/ConsensusContext.Get.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,29 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using Neo.Extensions;
using Neo.Network.P2P.Payloads;
using Neo.Plugins.DBFTPlugin.Messages;
using Neo.SmartContract;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;

namespace Neo.Plugins.DBFTPlugin.Consensus;

partial class ConsensusContext
{
public ConsensusMessage GetMessage(ExtensiblePayload payload)
[return: NotNullIfNotNull(nameof(payload))]
public ConsensusMessage? GetMessage(ExtensiblePayload? payload)
{
if (payload is null) return null;
if (!cachedMessages.TryGetValue(payload.Hash, out ConsensusMessage message))
if (!cachedMessages.TryGetValue(payload.Hash, out ConsensusMessage? message))
cachedMessages.Add(payload.Hash, message = ConsensusMessage.DeserializeFrom(payload.Data));
return message;
}

public T GetMessage<T>(ExtensiblePayload payload) where T : ConsensusMessage
[return: NotNullIfNotNull(nameof(payload))]
public T? GetMessage<T>(ExtensiblePayload? payload) where T : ConsensusMessage
{
return (T)GetMessage(payload);
return (T?)GetMessage(payload);
}

private RecoveryMessage.ChangeViewPayloadCompact GetChangeViewPayloadCompact(ExtensiblePayload payload)
Expand Down Expand Up @@ -82,7 +84,7 @@ public UInt160 GetSender(int index)
/// </summary>
public int GetExpectedBlockSize()
{
return GetExpectedBlockSizeWithoutTransactions(Transactions.Count) + // Base size
return GetExpectedBlockSizeWithoutTransactions(Transactions!.Count) + // Base size
Transactions.Values.Sum(u => u.Size); // Sum Txs
}

Expand All @@ -91,7 +93,7 @@ public int GetExpectedBlockSize()
/// </summary>
public long GetExpectedBlockSystemFee()
{
return Transactions.Values.Sum(u => u.SystemFee); // Sum Txs
return Transactions!.Values.Sum(u => u.SystemFee); // Sum Txs
}

/// <summary>
Expand Down
25 changes: 12 additions & 13 deletions plugins/DBFTPlugin/Consensus/ConsensusContext.MakePayload.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using Neo.Extensions;
using Neo.Ledger;
using Neo.Network.P2P.Payloads;
using Neo.Plugins.DBFTPlugin.Messages;
Expand All @@ -32,15 +31,15 @@ public ExtensiblePayload MakeChangeView(ChangeViewReason reason)

public ExtensiblePayload MakeCommit()
{
if (CommitPayloads[MyIndex] is not null)
return CommitPayloads[MyIndex];
if (CommitPayloads[MyIndex] is ExtensiblePayload payload)
return payload;

var block = EnsureHeader();
var block = EnsureHeader()!;
CommitPayloads[MyIndex] = MakeSignedPayload(new Commit
{
Signature = _signer.SignBlock(block, _myPublicKey, dbftSettings.Network)
Signature = _signer.SignBlock(block, _myPublicKey!, dbftSettings.Network)
});
return CommitPayloads[MyIndex];
return CommitPayloads[MyIndex]!;
}

private ExtensiblePayload MakeSignedPayload(ConsensusMessage message)
Expand Down Expand Up @@ -112,7 +111,7 @@ public ExtensiblePayload MakePrepareRequest()
PrevHash = Block.PrevHash,
Timestamp = Block.Timestamp,
Nonce = Block.Nonce,
TransactionHashes = TransactionHashes
TransactionHashes = TransactionHashes!
});
}

Expand All @@ -126,7 +125,7 @@ public ExtensiblePayload MakeRecoveryRequest()

public ExtensiblePayload MakeRecoveryMessage()
{
PrepareRequest prepareRequestMessage = null;
PrepareRequest? prepareRequestMessage = null;
if (TransactionHashes != null)
{
prepareRequestMessage = new PrepareRequest
Expand All @@ -144,23 +143,23 @@ public ExtensiblePayload MakeRecoveryMessage()
return MakeSignedPayload(new RecoveryMessage
{
ChangeViewMessages = LastChangeViewPayloads.Where(p => p != null)
.Select(p => GetChangeViewPayloadCompact(p))
.Select(p => GetChangeViewPayloadCompact(p!))
.Take(M)
.ToDictionary(p => p.ValidatorIndex),
PrepareRequestMessage = prepareRequestMessage,
// We only need a PreparationHash set if we don't have the PrepareRequest information.
PreparationHash = TransactionHashes == null
? PreparationPayloads.Where(p => p != null)
.GroupBy(p => GetMessage<PrepareResponse>(p).PreparationHash, (k, g) => new { Hash = k, Count = g.Count() })
.GroupBy(p => GetMessage<PrepareResponse>(p!).PreparationHash, (k, g) => new { Hash = k, Count = g.Count() })
.OrderByDescending(p => p.Count)
.Select(p => p.Hash)
.FirstOrDefault()
: null,
PreparationMessages = PreparationPayloads.Where(p => p != null)
.Select(p => GetPreparationPayloadCompact(p))
.Select(p => GetPreparationPayloadCompact(p!))
.ToDictionary(p => p.ValidatorIndex),
CommitMessages = CommitSent
? CommitPayloads.Where(p => p != null).Select(p => GetCommitPayloadCompact(p)).ToDictionary(p => p.ValidatorIndex)
? CommitPayloads.Where(p => p != null).Select(p => GetCommitPayloadCompact(p!)).ToDictionary(p => p.ValidatorIndex)
: new Dictionary<byte, RecoveryMessage.CommitPayloadCompact>()
});
}
Expand All @@ -169,7 +168,7 @@ public ExtensiblePayload MakePrepareResponse()
{
return PreparationPayloads[MyIndex] = MakeSignedPayload(new PrepareResponse
{
PreparationHash = PreparationPayloads[Block.PrimaryIndex].Hash
PreparationHash = PreparationPayloads[Block.PrimaryIndex]!.Hash
});
}

Expand Down
49 changes: 24 additions & 25 deletions plugins/DBFTPlugin/Consensus/ConsensusContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

using Neo.Cryptography;
using Neo.Cryptography.ECC;
using Neo.Extensions;
using Neo.Extensions.IO;
using Neo.IO;
using Neo.Ledger;
Expand All @@ -32,41 +31,41 @@ public sealed partial class ConsensusContext : IDisposable, ISerializable
/// </summary>
private static readonly byte[] ConsensusStateKey = { 0xf4 };

public Block Block;
public Block Block = null!;
public byte ViewNumber;
public TimeSpan TimePerBlock;
public ECPoint[] Validators;
public ECPoint[] Validators = null!;
public int MyIndex;
public UInt256[] TransactionHashes;
public Dictionary<UInt256, Transaction> Transactions;
public ExtensiblePayload[] PreparationPayloads;
public ExtensiblePayload[] CommitPayloads;
public ExtensiblePayload[] ChangeViewPayloads;
public ExtensiblePayload[] LastChangeViewPayloads;
public UInt256[]? TransactionHashes;
public Dictionary<UInt256, Transaction>? Transactions;
public ExtensiblePayload?[] PreparationPayloads = null!;
public ExtensiblePayload?[] CommitPayloads = null!;
public ExtensiblePayload?[] ChangeViewPayloads = null!;
public ExtensiblePayload?[] LastChangeViewPayloads = null!;
// LastSeenMessage array stores the height of the last seen message, for each validator.
// if this node never heard from validator i, LastSeenMessage[i] will be -1.
public Dictionary<ECPoint, uint> LastSeenMessage { get; private set; }
public Dictionary<ECPoint, uint>? LastSeenMessage { get; private set; }

/// <summary>
/// Store all verified unsorted transactions' senders' fee currently in the consensus context.
/// </summary>
public TransactionVerificationContext VerificationContext = new();

public StoreCache Snapshot { get; private set; }
private ECPoint _myPublicKey;
public StoreCache Snapshot { get; private set; } = null!;
private ECPoint? _myPublicKey;
private int _witnessSize;
private readonly NeoSystem neoSystem;
private readonly DbftSettings dbftSettings;
private readonly ISigner _signer;
private readonly IStore store;
private Dictionary<UInt256, ConsensusMessage> cachedMessages;
private readonly IStore? store;
private Dictionary<UInt256, ConsensusMessage> cachedMessages = null!;

public int F => (Validators.Length - 1) / 3;
public int M => Validators.Length - F;
public bool IsPrimary => MyIndex == Block.PrimaryIndex;
public bool IsBackup => MyIndex >= 0 && MyIndex != Block.PrimaryIndex;
public bool WatchOnly => MyIndex < 0;
public Header PrevHeader => NativeContract.Ledger.GetHeader(Snapshot, Block.PrevHash);
public Header PrevHeader => NativeContract.Ledger.GetHeader(Snapshot, Block.PrevHash)!;
public int CountCommitted => CommitPayloads.Count(p => p != null);
public int CountFailed
{
Expand All @@ -82,8 +81,8 @@ public bool ValidatorsChanged
{
if (NativeContract.Ledger.CurrentIndex(Snapshot) == 0) return false;
UInt256 hash = NativeContract.Ledger.CurrentHash(Snapshot);
TrimmedBlock currentBlock = NativeContract.Ledger.GetTrimmedBlock(Snapshot, hash);
TrimmedBlock previousBlock = NativeContract.Ledger.GetTrimmedBlock(Snapshot, currentBlock.Header.PrevHash);
TrimmedBlock currentBlock = NativeContract.Ledger.GetTrimmedBlock(Snapshot, hash)!;
TrimmedBlock previousBlock = NativeContract.Ledger.GetTrimmedBlock(Snapshot, currentBlock.Header.PrevHash)!;
return currentBlock.Header.NextConsensus != previousBlock.Header.NextConsensus;
}
}
Expand Down Expand Up @@ -128,11 +127,11 @@ public Block CreateBlock()
for (int i = 0, j = 0; i < Validators.Length && j < M; i++)
{
if (GetMessage(CommitPayloads[i])?.ViewNumber != ViewNumber) continue;
sc.AddSignature(contract, Validators[i], GetMessage<Commit>(CommitPayloads[i]).Signature.ToArray());
sc.AddSignature(contract, Validators[i], GetMessage<Commit>(CommitPayloads[i]!).Signature.ToArray());
j++;
}
Block.Header.Witness = sc.GetWitnesses()[0];
Block.Transactions = TransactionHashes.Select(p => Transactions[p]).ToArray();
Block.Transactions = TransactionHashes!.Select(p => Transactions![p]).ToArray();
return Block;
}

Expand All @@ -145,7 +144,7 @@ public ExtensiblePayload CreatePayload(ConsensusMessage message, ReadOnlyMemory<
ValidBlockEnd = message.BlockIndex,
Sender = GetSender(message.ValidatorIndex),
Data = message.ToArray(),
Witness = invocationScript.IsEmpty ? null : new Witness
Witness = invocationScript.IsEmpty ? null! : new Witness
{
InvocationScript = invocationScript,
VerificationScript = Contract.CreateSignatureRedeemScript(Validators[message.ValidatorIndex])
Expand All @@ -160,7 +159,7 @@ public void Dispose()
Snapshot?.Dispose();
}

public Block EnsureHeader()
public Block? EnsureHeader()
{
if (TransactionHashes == null) return null;
Block.Header.MerkleRoot ??= MerkleTree.ComputeRoot(TransactionHashes);
Expand Down Expand Up @@ -267,13 +266,13 @@ public void Reset(byte viewNumber)
}
ViewNumber = viewNumber;
Block.Header.PrimaryIndex = GetPrimaryIndex(viewNumber);
Block.Header.MerkleRoot = null;
Block.Header.MerkleRoot = null!;
Block.Header.Timestamp = 0;
Block.Header.Nonce = 0;
Block.Transactions = null;
Block.Transactions = null!;
TransactionHashes = null;
PreparationPayloads = new ExtensiblePayload[Validators.Length];
if (MyIndex >= 0) LastSeenMessage[Validators[MyIndex]] = Block.Index;
if (MyIndex >= 0) LastSeenMessage![Validators[MyIndex]] = Block.Index;
}

public void Save()
Expand All @@ -295,7 +294,7 @@ public void Deserialize(ref MemoryReader reader)
Block.Header.PrimaryIndex = reader.ReadByte();
Block.Header.NextConsensus = reader.ReadSerializable<UInt160>();
if (Block.NextConsensus.Equals(UInt160.Zero))
Block.Header.NextConsensus = null;
Block.Header.NextConsensus = null!;
ViewNumber = reader.ReadByte();
TransactionHashes = reader.ReadSerializableArray<UInt256>(ushort.MaxValue);
Transaction[] transactions = reader.ReadSerializableArray<Transaction>(ushort.MaxValue);
Expand Down
8 changes: 4 additions & 4 deletions plugins/DBFTPlugin/Consensus/ConsensusService.Check.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ partial class ConsensusService
{
private bool CheckPrepareResponse()
{
if (context.TransactionHashes.Length == context.Transactions.Count)
if (context.TransactionHashes!.Length == context.Transactions!.Count)
{
// if we are the primary for this view, but acting as a backup because we recovered our own
// previously sent prepare request, then we don't want to send a prepare response.
Expand Down Expand Up @@ -55,7 +55,7 @@ private bool CheckPrepareResponse()

private void CheckCommits()
{
if (context.CommitPayloads.Count(p => context.GetMessage(p)?.ViewNumber == context.ViewNumber) >= context.M && context.TransactionHashes.All(p => context.Transactions.ContainsKey(p)))
if (context.CommitPayloads.Count(p => context.GetMessage(p)?.ViewNumber == context.ViewNumber) >= context.M && context.TransactionHashes!.All(p => context.Transactions!.ContainsKey(p)))
{
block_received_index = context.Block.Index;
Block block = context.CreateBlock();
Expand All @@ -73,7 +73,7 @@ private void CheckExpectedView(byte viewNumber)
{
if (!context.WatchOnly)
{
ChangeView message = messages[context.MyIndex];
ChangeView? message = messages[context.MyIndex];
// Communicate the network about my agreement to move to `viewNumber`
// if my last change view payload, `message`, has NewViewNumber lower than current view to change
if (message is null || message.NewViewNumber < viewNumber)
Expand All @@ -85,7 +85,7 @@ private void CheckExpectedView(byte viewNumber)

private void CheckPreparations()
{
if (context.PreparationPayloads.Count(p => p != null) >= context.M && context.TransactionHashes.All(p => context.Transactions.ContainsKey(p)))
if (context.PreparationPayloads.Count(p => p != null) >= context.M && context.TransactionHashes!.All(p => context.Transactions!.ContainsKey(p)))
{
ExtensiblePayload payload = context.MakeCommit();
Log($"Sending {nameof(Commit)}");
Expand Down
19 changes: 9 additions & 10 deletions plugins/DBFTPlugin/Consensus/ConsensusService.OnMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

using Akka.Actor;
using Neo.Cryptography;
using Neo.Extensions;
using Neo.Ledger;
using Neo.Network.P2P;
using Neo.Network.P2P.Payloads;
Expand Down Expand Up @@ -48,7 +47,7 @@ private void OnConsensusPayload(ExtensiblePayload payload)
}
if (message.ValidatorIndex >= context.Validators.Length) return;
if (payload.Sender != Contract.CreateSignatureRedeemScript(context.Validators[message.ValidatorIndex]).ToScriptHash()) return;
context.LastSeenMessage[context.Validators[message.ValidatorIndex]] = message.BlockIndex;
context.LastSeenMessage?[context.Validators[message.ValidatorIndex]] = message.BlockIndex;
switch (message)
{
case PrepareRequest request:
Expand Down Expand Up @@ -106,13 +105,13 @@ private void OnPrepareRequestReceived(ExtensiblePayload payload, PrepareRequest
context.VerificationContext = new TransactionVerificationContext();
for (int i = 0; i < context.PreparationPayloads.Length; i++)
if (context.PreparationPayloads[i] != null)
if (!context.GetMessage<PrepareResponse>(context.PreparationPayloads[i]).PreparationHash.Equals(payload.Hash))
if (!context.GetMessage<PrepareResponse>(context.PreparationPayloads[i]!).PreparationHash.Equals(payload.Hash))
context.PreparationPayloads[i] = null;
context.PreparationPayloads[message.ValidatorIndex] = payload;
byte[] hashData = context.EnsureHeader().GetSignData(neoSystem.Settings.Network);
byte[] hashData = context.EnsureHeader()!.GetSignData(neoSystem.Settings.Network);
for (int i = 0; i < context.CommitPayloads.Length; i++)
if (context.GetMessage(context.CommitPayloads[i])?.ViewNumber == context.ViewNumber)
if (!Crypto.VerifySignature(hashData, context.GetMessage<Commit>(context.CommitPayloads[i]).Signature.Span, context.Validators[i]))
if (!Crypto.VerifySignature(hashData, context.GetMessage<Commit>(context.CommitPayloads[i]!).Signature.Span, context.Validators[i]))
context.CommitPayloads[i] = null;

if (context.TransactionHashes.Length == 0)
Expand All @@ -127,7 +126,7 @@ private void OnPrepareRequestReceived(ExtensiblePayload payload, PrepareRequest
var mtb = neoSystem.Settings.MaxTraceableBlocks;
foreach (UInt256 hash in context.TransactionHashes)
{
if (mempoolVerified.TryGetValue(hash, out Transaction tx))
if (mempoolVerified.TryGetValue(hash, out Transaction? tx))
{
if (NativeContract.Ledger.ContainsConflictHash(context.Snapshot, hash, tx.Signers.Select(s => s.Account), mtb))
{
Expand Down Expand Up @@ -165,7 +164,7 @@ private void OnPrepareResponseReceived(ExtensiblePayload payload, PrepareRespons
{
if (message.ViewNumber != context.ViewNumber) return;
if (context.PreparationPayloads[message.ValidatorIndex] != null || context.NotAcceptingPayloadsDueToViewChanging) return;
if (context.PreparationPayloads[context.Block.PrimaryIndex] != null && !message.PreparationHash.Equals(context.PreparationPayloads[context.Block.PrimaryIndex].Hash))
if (context.PreparationPayloads[context.Block.PrimaryIndex] != null && !message.PreparationHash.Equals(context.PreparationPayloads[context.Block.PrimaryIndex]!.Hash))
return;

// Timeout extension: prepare response has been received with success
Expand Down Expand Up @@ -197,7 +196,7 @@ private void OnChangeViewReceived(ExtensiblePayload payload, ChangeView message)

private void OnCommitReceived(ExtensiblePayload payload, Commit commit)
{
ref ExtensiblePayload existingCommitPayload = ref context.CommitPayloads[commit.ValidatorIndex];
ref ExtensiblePayload? existingCommitPayload = ref context.CommitPayloads[commit.ValidatorIndex];
if (existingCommitPayload != null)
{
if (existingCommitPayload.Hash != payload.Hash)
Expand All @@ -213,7 +212,7 @@ private void OnCommitReceived(ExtensiblePayload payload, Commit commit)

Log($"{nameof(OnCommitReceived)}: height={commit.BlockIndex} view={commit.ViewNumber} index={commit.ValidatorIndex} nc={context.CountCommitted} nf={context.CountFailed}");

byte[] hashData = context.EnsureHeader()?.GetSignData(neoSystem.Settings.Network);
byte[]? hashData = context.EnsureHeader()?.GetSignData(neoSystem.Settings.Network);
if (hashData == null)
{
existingCommitPayload = payload;
Expand Down Expand Up @@ -254,7 +253,7 @@ private void OnRecoveryMessageReceived(RecoveryMessage message)
{
if (!context.RequestSentOrReceived)
{
ExtensiblePayload prepareRequestPayload = message.GetPrepareRequestPayload(context);
ExtensiblePayload? prepareRequestPayload = message.GetPrepareRequestPayload(context);
if (prepareRequestPayload != null)
{
totalPrepReq = 1;
Expand Down
Loading