Skip to content

Commit

Permalink
Pick some changes from #575.
Browse files Browse the repository at this point in the history
  • Loading branch information
erikzhang committed Feb 21, 2019
1 parent 2311524 commit bbcfc68
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 46 deletions.
21 changes: 10 additions & 11 deletions neo.UnitTests/UT_Consensus.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Security.Cryptography;
using ECPoint = Neo.Cryptography.ECC.ECPoint;

Expand Down Expand Up @@ -179,20 +178,20 @@ public void TestSerializeAndDeserializeConsensusContext()
{
var consensusContext = new ConsensusContext(null);
consensusContext.State = ConsensusState.CommitSent;
consensusContext.PrevHash = UInt256.Parse("3333333377777777333333337777777733333333777777773333333377777777");
consensusContext.BlockIndex = 1337;
consensusContext.PrevHash = UInt256.Parse("0xd42561e3d30e15be6400b6df2f328e02d2bf6354c41dce433bc57687c82144bf");
consensusContext.BlockIndex = 1;
consensusContext.ViewNumber = 2;
consensusContext.Validators = new ECPoint[7]
{
TestUtils.StandbyValidators[0],
ECPoint.Multiply(TestUtils.StandbyValidators[0], new BigInteger(2)),
ECPoint.Multiply(TestUtils.StandbyValidators[0], new BigInteger(3)),
ECPoint.Multiply(TestUtils.StandbyValidators[0], new BigInteger(4)),
ECPoint.Multiply(TestUtils.StandbyValidators[0], new BigInteger(5)),
ECPoint.Multiply(TestUtils.StandbyValidators[0], new BigInteger(6)),
ECPoint.Multiply(TestUtils.StandbyValidators[0], new BigInteger(7)),
ECPoint.Parse("02486fd15702c4490a26703112a5cc1d0923fd697a33406bd5a1c00e0013b09a70", Cryptography.ECC.ECCurve.Secp256r1),
ECPoint.Parse("024c7b7fb6c310fccf1ba33b082519d82964ea93868d676662d4a59ad548df0e7d", Cryptography.ECC.ECCurve.Secp256r1),
ECPoint.Parse("02aaec38470f6aad0042c6e877cfd8087d2676b0f516fddd362801b9bd3936399e", Cryptography.ECC.ECCurve.Secp256r1),
ECPoint.Parse("02ca0e27697b9c248f6f16e085fd0061e26f44da85b58ee835c110caa5ec3ba554", Cryptography.ECC.ECCurve.Secp256r1),
ECPoint.Parse("02df48f60e8f3e01c48ff40b9b7f1310d7a8b2a193188befe1c2e3df740e895093", Cryptography.ECC.ECCurve.Secp256r1),
ECPoint.Parse("03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c", Cryptography.ECC.ECCurve.Secp256r1),
ECPoint.Parse("03b8d9d5771d8f513aa0869b9cc8d50986403b78c6da36890638c3d46a5adce04a", Cryptography.ECC.ECCurve.Secp256r1)
};
consensusContext.MyIndex = 3;
consensusContext.MyIndex = -1;
consensusContext.PrimaryIndex = 6;
consensusContext.Timestamp = 4244941711;
consensusContext.Nonce = UInt64.MaxValue;
Expand Down
21 changes: 8 additions & 13 deletions neo/Consensus/ConsensusContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@ namespace Neo.Consensus
internal class ConsensusContext : IConsensusContext
{
public const uint Version = 0;
public ConsensusState State { get; set; }
public UInt256 PrevHash { get; set; }
public uint BlockIndex { get; set; }
public UInt256 PrevHash { get; set; }
public byte ViewNumber { get; set; }
public ECPoint[] Validators { get; set; }
public int MyIndex { get; set; }
Expand All @@ -33,6 +32,7 @@ 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 Snapshot Snapshot { get; private set; }
private KeyPair keyPair;
private readonly Wallet wallet;
Expand Down Expand Up @@ -66,13 +66,10 @@ public Block CreateBlock()

public void Deserialize(BinaryReader reader)
{
if (reader.ReadUInt32() != Version) return;
State = (ConsensusState)reader.ReadByte();
PrevHash = reader.ReadSerializable<UInt256>();
BlockIndex = reader.ReadUInt32();
Reset(0);
if (reader.ReadUInt32() != Version) throw new FormatException();
if (reader.ReadUInt32() != BlockIndex) throw new InvalidOperationException();
ViewNumber = reader.ReadByte();
Validators = reader.ReadSerializableArray<ECPoint>();
MyIndex = reader.ReadInt32();
PrimaryIndex = reader.ReadUInt32();
Timestamp = reader.ReadUInt32();
Nonce = reader.ReadUInt64();
Expand Down Expand Up @@ -105,6 +102,7 @@ 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()
Expand Down Expand Up @@ -251,7 +249,7 @@ public void Reset(byte viewNumber)
keyPair = null;
for (int i = 0; i < Validators.Length; i++)
{
WalletAccount account = wallet.GetAccount(Validators[i]);
WalletAccount account = wallet?.GetAccount(Validators[i]);
if (account?.HasKey != true) continue;
MyIndex = i;
keyPair = account.GetKey();
Expand Down Expand Up @@ -279,12 +277,8 @@ public void Reset(byte viewNumber)
public void Serialize(BinaryWriter writer)
{
writer.Write(Version);
writer.Write((byte)State);
writer.Write(PrevHash);
writer.Write(BlockIndex);
writer.Write(ViewNumber);
writer.Write(Validators);
writer.Write(MyIndex);
writer.Write(PrimaryIndex);
writer.Write(Timestamp);
writer.Write(Nonce);
Expand Down Expand Up @@ -323,6 +317,7 @@ public void Serialize(BinaryWriter writer)
if (!hasPayload) continue;
writer.Write(payload);
}
writer.Write((byte)State);
}

public void Fill()
Expand Down
31 changes: 9 additions & 22 deletions neo/Consensus/ConsensusService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
using Neo.Wallets;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace Neo.Consensus
Expand All @@ -22,8 +21,6 @@ public class Start { public bool IgnoreRecoveryLogs; }
public class SetViewNumber { public byte ViewNumber; }
internal class Timer { public uint Height; public byte ViewNumber; }

private const byte ContextSerializationPrefix = 0xf4;

private readonly IConsensusContext context;
private readonly IActorRef localNode;
private readonly IActorRef taskManager;
Expand Down Expand Up @@ -128,7 +125,7 @@ private void CheckPreparations()
ConsensusPayload payload = context.MakeCommit();
Log($"send commit");
context.State |= ConsensusState.CommitSent;
store.Put(ContextSerializationPrefix, new byte[0], context.ToArray());
context.Save(store);
localNode.Tell(new LocalNode.SendDirectly { Inventory = payload });
// Set timer, so we will resend the commit in case of a networking issue
ChangeTimer(TimeSpan.FromSeconds(Blockchain.SecondsPerBlock));
Expand Down Expand Up @@ -433,27 +430,17 @@ private void OnStart(Start options)
{
Log("OnStart");
started = true;
if (!options.IgnoreRecoveryLogs)
bool loadedState = !options.IgnoreRecoveryLogs && context.Load(store);
if (loadedState && context.State.HasFlag(ConsensusState.CommitSent))
{
byte[] data = store.Get(ContextSerializationPrefix, new byte[0]);
if (data != null)
{
using (MemoryStream ms = new MemoryStream(data, false))
using (BinaryReader reader = new BinaryReader(ms))
{
context.Deserialize(reader);
}
}
}
if (context.State.HasFlag(ConsensusState.CommitSent) && context.BlockIndex == Blockchain.Singleton.Height + 1)
CheckPreparations();
else
{
InitializeConsensus(0);
// Issue a ChangeView with NewViewNumber of 0 to request recovery messages on start-up.
if (context.BlockIndex == Blockchain.Singleton.HeaderHeight + 1)
localNode.Tell(new LocalNode.SendDirectly { Inventory = context.MakeChangeView(0) });
return;
}

InitializeConsensus(0);
// Issue a ChangeView with NewViewNumber of 0 to request recovery messages on start-up.
if (context.BlockIndex == Blockchain.Singleton.HeaderHeight + 1)
localNode.Tell(new LocalNode.SendDirectly { Inventory = context.MakeChangeView(0) });
}

private void OnTimer(Timer timer)
Expand Down
38 changes: 38 additions & 0 deletions neo/Consensus/Helper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using Neo.IO;
using Neo.Persistence;
using System.IO;

namespace Neo.Consensus
{
internal static class Helper
{
/// <summary>
/// Prefix for saving consensus state.
/// </summary>
public const byte CN_Context = 0xf4;

public static void Save(this IConsensusContext context, Store store)
{
store.PutSync(CN_Context, new byte[0], context.ToArray());
}

public static bool Load(this IConsensusContext context, Store store)
{
byte[] data = store.Get(CN_Context, new byte[0]);
if (data is null) return false;
using (MemoryStream ms = new MemoryStream(data, false))
using (BinaryReader reader = new BinaryReader(ms))
{
try
{
context.Deserialize(reader);
}
catch
{
return false;
}
return true;
}
}
}
}
5 changes: 5 additions & 0 deletions neo/Persistence/LevelDB/LevelDBStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,5 +116,10 @@ public override void Put(byte prefix, byte[] key, byte[] value)
{
db.Put(WriteOptions.Default, SliceBuilder.Begin(prefix).Add(key), value);
}

public override void PutSync(byte prefix, byte[] key, byte[] value)
{
db.Put(new WriteOptions { Sync = true }, SliceBuilder.Begin(prefix).Add(key), value);
}
}
}
5 changes: 5 additions & 0 deletions neo/Persistence/LevelDB/Prefixes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,10 @@ internal static class Prefixes
public const byte IX_CurrentHeader = 0xc1;

public const byte SYS_Version = 0xf0;

/* Prefixes 0xf1 to 0xff are reserved for external use.
*
* Note: The saved consensus state uses the Prefix 0xf4
*/
}
}
1 change: 1 addition & 0 deletions neo/Persistence/Store.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public abstract class Store : IPersistence
public abstract MetaDataCache<HashIndexState> GetBlockHashIndex();
public abstract MetaDataCache<HashIndexState> GetHeaderHashIndex();
public abstract void Put(byte prefix, byte[] key, byte[] value);
public abstract void PutSync(byte prefix, byte[] key, byte[] value);

public abstract Snapshot GetSnapshot();
}
Expand Down

0 comments on commit bbcfc68

Please sign in to comment.