Skip to content

Commit

Permalink
Refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
erikzhang committed Feb 25, 2019
1 parent de64019 commit eaeb0a5
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 119 deletions.
7 changes: 2 additions & 5 deletions neo.UnitTests/UT_Consensus.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,8 @@ public void ConsensusService_Primary_Sends_PrepareRequest_After_OnStart()
mockConsensusContext.SetupProperty(mr => mr.Nonce);
mockConsensusContext.SetupProperty(mr => mr.NextConsensus);
mockConsensusContext.Object.NextConsensus = UInt160.Zero;
mockConsensusContext.Setup(mr => mr.GetPrimaryIndex(It.IsAny<byte>())).Returns(2);
mockConsensusContext.SetupProperty(mr => mr.State); // allows get and set to update mock state on Initialize method
mockConsensusContext.Object.State = ConsensusState.Initial;
mockConsensusContext.SetupGet(mr => mr.PreparationPayloads).Returns(new ConsensusPayload[7]);
mockConsensusContext.SetupGet(mr => mr.CommitPayloads).Returns(new ConsensusPayload[7]);

int timeIndex = 0;
var timeValues = new[] {
Expand Down Expand Up @@ -177,7 +176,6 @@ public void ConsensusService_Primary_Sends_PrepareRequest_After_OnStart()
public void TestSerializeAndDeserializeConsensusContext()
{
var consensusContext = new ConsensusContext(null);
consensusContext.State = ConsensusState.CommitSent;
consensusContext.PrevHash = UInt256.Parse("0xd42561e3d30e15be6400b6df2f328e02d2bf6354c41dce433bc57687c82144bf");
consensusContext.BlockIndex = 1;
consensusContext.ViewNumber = 2;
Expand Down Expand Up @@ -252,7 +250,6 @@ public void TestSerializeAndDeserializeConsensusContext()

var copiedContext = TestUtils.CopyMsgBySerialization(consensusContext, new ConsensusContext(null));

copiedContext.State.Should().Be(consensusContext.State);
copiedContext.PrevHash.Should().Be(consensusContext.PrevHash);
copiedContext.BlockIndex.Should().Be(consensusContext.BlockIndex);
copiedContext.ViewNumber.Should().Be(consensusContext.ViewNumber);
Expand Down
62 changes: 22 additions & 40 deletions neo/Consensus/ConsensusContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,11 @@ internal class ConsensusContext : IConsensusContext
public ConsensusPayload[] CommitPayloads { get; set; }
public ConsensusPayload[] ChangeViewPayloads { get; set; }
public ConsensusPayload[] LastChangeViewPayloads { get; set; }
public ConsensusState State { get; set; }
public Block Block { get; set; }
public Snapshot Snapshot { get; private set; }
private KeyPair keyPair;
private readonly Wallet wallet;

public int F => (Validators.Length - 1) / 3;
public int M => Validators.Length - F;
public Header PrevHeader => Snapshot.GetHeader(PrevHash);
public int Size => throw new NotImplementedException();

public ConsensusContext(Wallet wallet)
Expand All @@ -49,19 +46,22 @@ public ConsensusContext(Wallet wallet)

public Block CreateBlock()
{
Block block = MakeHeader();
if (block == null) return null;
Contract contract = Contract.CreateMultiSigContract(M, Validators);
ContractParametersContext sc = new ContractParametersContext(block);
for (int i = 0, j = 0; i < Validators.Length && j < M; i++)
if (Block is null)
{
if (CommitPayloads[i] == null) continue;
sc.AddSignature(contract, Validators[i], CommitPayloads[i].GetDeserializedMessage<Commit>().Signature);
j++;
Block = MakeHeader();
if (Block == null) return null;
Contract contract = Contract.CreateMultiSigContract(this.M(), Validators);
ContractParametersContext sc = new ContractParametersContext(Block);
for (int i = 0, j = 0; i < Validators.Length && j < this.M(); i++)
{
if (CommitPayloads[i] == null) continue;
sc.AddSignature(contract, Validators[i], CommitPayloads[i].GetDeserializedMessage<Commit>().Signature);
j++;
}
sc.Verifiable.Witnesses = sc.GetWitnesses();
Block.Transactions = TransactionHashes.Select(p => Transactions[p]).ToArray();
}
sc.Verifiable.Witnesses = sc.GetWitnesses();
block.Transactions = TransactionHashes.Select(p => Transactions[p]).ToArray();
return block;
return Block;
}

public void Deserialize(BinaryReader reader)
Expand Down Expand Up @@ -102,20 +102,13 @@ public void Deserialize(BinaryReader reader)
LastChangeViewPayloads = new ConsensusPayload[reader.ReadVarInt()];
for (int i = 0; i < LastChangeViewPayloads.Length; i++)
LastChangeViewPayloads[i] = reader.ReadBoolean() ? reader.ReadSerializable<ConsensusPayload>() : null;
State = (ConsensusState)reader.ReadByte();
}

public void Dispose()
{
Snapshot?.Dispose();
}

public uint GetPrimaryIndex(byte viewNumber)
{
int p = ((int)BlockIndex - viewNumber) % Validators.Length;
return p >= 0 ? (uint)p : (uint)(p + Validators.Length);
}

public ConsensusPayload MakeChangeView(byte newViewNumber)
{
return ChangeViewPayloads[MyIndex] = MakeSignedPayload(new ChangeView
Expand Down Expand Up @@ -188,7 +181,8 @@ private void SignPayload(ConsensusPayload payload)

public ConsensusPayload MakePrepareRequest()
{
return MakeSignedPayload(new PrepareRequest
Fill();
return PreparationPayloads[MyIndex] = MakeSignedPayload(new PrepareRequest
{
Timestamp = Timestamp,
Nonce = Nonce,
Expand All @@ -215,12 +209,12 @@ public ConsensusPayload MakeRecoveryMessage()
}
return MakeSignedPayload(new RecoveryMessage()
{
ChangeViewMessages = LastChangeViewPayloads.Where(p => p != null).Select(p => RecoveryMessage.ChangeViewPayloadCompact.FromPayload(p)).Take(M).ToDictionary(p => (int)p.ValidatorIndex),
ChangeViewMessages = LastChangeViewPayloads.Where(p => p != null).Select(p => RecoveryMessage.ChangeViewPayloadCompact.FromPayload(p)).Take(this.M()).ToDictionary(p => (int)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 => p.GetDeserializedMessage<PrepareResponse>().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 => RecoveryMessage.PreparationPayloadCompact.FromPayload(p)).ToDictionary(p => (int)p.ValidatorIndex),
CommitMessages = State.HasFlag(ConsensusState.CommitSent)
CommitMessages = this.CommitSent()
? CommitPayloads.Where(p => p != null).Select(p => RecoveryMessage.CommitPayloadCompact.FromPayload(p)).ToDictionary(p => (int)p.ValidatorIndex)
: new Dictionary<int, RecoveryMessage.CommitPayloadCompact>()
});
Expand Down Expand Up @@ -264,9 +258,8 @@ public void Reset(byte viewNumber)
else
LastChangeViewPayloads[i] = null;
}
State = ConsensusState.Initial;
ViewNumber = viewNumber;
PrimaryIndex = GetPrimaryIndex(viewNumber);
PrimaryIndex = this.GetPrimaryIndex(viewNumber);
Timestamp = 0;
TransactionHashes = null;
PreparationPayloads = new ConsensusPayload[Validators.Length];
Expand Down Expand Up @@ -317,10 +310,9 @@ public void Serialize(BinaryWriter writer)
if (!hasPayload) continue;
writer.Write(payload);
}
writer.Write((byte)State);
}

public void Fill()
private void Fill()
{
IEnumerable<Transaction> memoryPoolTransactions = Blockchain.Singleton.MemPool.GetSortedVerifiedTransactions();
foreach (IPolicyPlugin plugin in Plugin.Policies)
Expand Down Expand Up @@ -354,7 +346,7 @@ public void Fill()
TransactionHashes = transactions.Select(p => p.Hash).ToArray();
Transactions = transactions.ToDictionary(p => p.Hash);
NextConsensus = Blockchain.GetConsensusAddress(Snapshot.GetValidators(transactions).ToArray());
Timestamp = Math.Max(TimeProvider.Current.UtcNow.ToTimestamp(), PrevHeader.Timestamp + 1);
Timestamp = Math.Max(TimeProvider.Current.UtcNow.ToTimestamp(), this.PrevHeader().Timestamp + 1);
}

private static ulong GetNonce()
Expand All @@ -364,15 +356,5 @@ private static ulong GetNonce()
rand.NextBytes(nonce);
return nonce.ToUInt64(0);
}

public bool VerifyRequest()
{
if (!Blockchain.GetConsensusAddress(Snapshot.GetValidators(Transactions.Values).ToArray()).Equals(NextConsensus))
return false;
Transaction minerTx = Transactions.Values.FirstOrDefault(p => p.Type == TransactionType.MinerTransaction);
Fixed8 amountNetFee = Block.CalculateNetFee(Transactions.Values);
if (minerTx?.Outputs.Sum(p => p.Value) != amountNetFee) return false;
return true;
}
}
}
Loading

0 comments on commit eaeb0a5

Please sign in to comment.