From 919962bff6ac9ce3632769dafb92ac4d5188f33f Mon Sep 17 00:00:00 2001 From: zhangtao Date: Fri, 22 May 2020 17:07:10 +0800 Subject: [PATCH] [neox-2.x] StateHeight start from -1 (#1658) * StateHeight start from -1 * add RootHashIndex * fix ut --- neo.UnitTests/TestBlockchain.cs | 4 +- neo/Ledger/BlockChain.State.cs | 10 ++--- neo/Ledger/RootHashIndex.cs | 51 +++++++++++++++++++++++++ neo/Network/P2P/TaskManager.cs | 6 +-- neo/Persistence/CloneSnapshot.cs | 2 +- neo/Persistence/IPersistence.cs | 2 +- neo/Persistence/LevelDB/DbSnapshot.cs | 12 +----- neo/Persistence/LevelDB/LevelDBStore.cs | 4 +- neo/Persistence/Snapshot.cs | 4 +- neo/Persistence/Store.cs | 4 +- 10 files changed, 71 insertions(+), 28 deletions(-) create mode 100644 neo/Ledger/RootHashIndex.cs diff --git a/neo.UnitTests/TestBlockchain.cs b/neo.UnitTests/TestBlockchain.cs index 6947350172..9e481e4e61 100644 --- a/neo.UnitTests/TestBlockchain.cs +++ b/neo.UnitTests/TestBlockchain.cs @@ -31,7 +31,7 @@ public static NeoSystem InitializeMockNeoSystem() mockSnapshot.SetupGet(p => p.ValidatorsCount).Returns(new TestMetaDataCache()); mockSnapshot.SetupGet(p => p.BlockHashIndex).Returns(new TestMetaDataCache()); mockSnapshot.SetupGet(p => p.HeaderHashIndex).Returns(new TestMetaDataCache()); - mockSnapshot.SetupGet(p => p.StateRootHashIndex).Returns(new TestMetaDataCache()); + mockSnapshot.SetupGet(p => p.StateRootHashIndex).Returns(new TestMetaDataCache()); var mockStore = new Mock(); @@ -55,7 +55,7 @@ public static NeoSystem InitializeMockNeoSystem() mockStore.Setup(p => p.GetValidatorsCount()).Returns(new TestMetaDataCache()); mockStore.Setup(p => p.GetBlockHashIndex()).Returns(new TestMetaDataCache()); mockStore.Setup(p => p.GetHeaderHashIndex()).Returns(new TestMetaDataCache()); - mockStore.Setup(p => p.GetStateRootHashIndex()).Returns(new TestMetaDataCache()); + mockStore.Setup(p => p.GetStateRootHashIndex()).Returns(new TestMetaDataCache()); mockStore.Setup(p => p.GetSnapshot()).Returns(mockSnapshot.Object); mockStore.Setup(p => p.Get(It.IsAny(), It.IsAny())).Returns(UInt256.Zero.ToArray()); Console.WriteLine("initialize NeoSystem"); diff --git a/neo/Ledger/BlockChain.State.cs b/neo/Ledger/BlockChain.State.cs index 4acd96526b..6b718e575c 100644 --- a/neo/Ledger/BlockChain.State.cs +++ b/neo/Ledger/BlockChain.State.cs @@ -13,7 +13,7 @@ namespace Neo.Ledger public sealed partial class Blockchain : UntypedActor { public class ImportRoots { public IEnumerable Roots; } - public uint StateHeight => currentSnapshot.StateHeight; + public long StateHeight => currentSnapshot.StateHeight; private static uint StateRootEnableIndex => ProtocolSettings.Default.StateRootEnableIndex; private readonly Dictionary stateRootCache = new Dictionary(); @@ -103,9 +103,9 @@ private StateRootVerifyFlag PersistCnStateRoot(StateRoot stateRoot) var localState = snapshot.StateRoots.GetAndChange(stateRoot.Index); if (localState.StateRoot.Root == stateRoot.Root && localState.StateRoot.PreHash == stateRoot.PreHash) { - HashIndexState hashIndexState = snapshot.StateRootHashIndex.GetAndChange(); - hashIndexState.Index = stateRoot.Index; - hashIndexState.Hash = stateRoot.Hash; + RootHashIndex rootHashIndex = snapshot.StateRootHashIndex.GetAndChange(); + rootHashIndex.Index = stateRoot.Index; + rootHashIndex.Hash = stateRoot.Hash; localState.StateRoot = stateRoot; localState.Flag = StateRootVerifyFlag.Verified; } @@ -152,7 +152,7 @@ private void PersistLocalStateRoot() private void CheckRootOnBlockPersistCompleted() { - var index = Math.Max(StateHeight + 1, StateRootEnableIndex); + var index = (uint)Math.Max(StateHeight + 1, StateRootEnableIndex); if (GetStateRoot(index)?.Flag == StateRootVerifyFlag.Unverified && stateRootCache.TryGetValue(index, out StateRoot state_root)) { stateRootCache.Remove(index); diff --git a/neo/Ledger/RootHashIndex.cs b/neo/Ledger/RootHashIndex.cs new file mode 100644 index 0000000000..e123fc94d4 --- /dev/null +++ b/neo/Ledger/RootHashIndex.cs @@ -0,0 +1,51 @@ +using Neo.IO; +using Neo.IO.Json; +using System.IO; + +namespace Neo.Ledger +{ + public class RootHashIndex : StateBase, ICloneable + { + public UInt256 Hash = UInt256.Zero; + public long Index = -1; + + public override int Size => base.Size + Hash.Size + sizeof(long); + + RootHashIndex ICloneable.Clone() + { + return new RootHashIndex + { + Hash = Hash, + Index = Index + }; + } + + public override void Deserialize(BinaryReader reader) + { + base.Deserialize(reader); + Hash = reader.ReadSerializable(); + Index = reader.ReadInt64(); + } + + void ICloneable.FromReplica(RootHashIndex replica) + { + Hash = replica.Hash; + Index = replica.Index; + } + + public override void Serialize(BinaryWriter writer) + { + base.Serialize(writer); + writer.Write(Hash); + writer.Write(Index); + } + + public override JObject ToJson() + { + JObject json = base.ToJson(); + json["hash"] = Hash.ToString(); + json["index"] = Index; + return json; + } + } +} diff --git a/neo/Network/P2P/TaskManager.cs b/neo/Network/P2P/TaskManager.cs index 9c65245314..aa28fa0645 100644 --- a/neo/Network/P2P/TaskManager.cs +++ b/neo/Network/P2P/TaskManager.cs @@ -275,14 +275,14 @@ private void RequestTasks(TaskSession session) } if (!HasStateRootTask) { - var state_height = Math.Max(Blockchain.Singleton.StateHeight, ProtocolSettings.Default.StateRootEnableIndex - 1); + var state_height = Math.Max(Blockchain.Singleton.StateHeight, (long)ProtocolSettings.Default.StateRootEnableIndex - 1); var height = Blockchain.Singleton.Height; if (state_height + 1 < height) { - var state = Blockchain.Singleton.GetStateRoot(state_height + 1); + var state = Blockchain.Singleton.GetStateRoot((uint)(state_height + 1)); if (state is null || state.Flag == StateRootVerifyFlag.Unverified) { - var start_index = state_height + 1; + var start_index = (uint)(state_height + 1); var count = Math.Min(height - start_index, StateRootsPayload.MaxStateRootsCount); session.Tasks[StateRootTaskHash] = DateTime.UtcNow; IncrementGlobalTask(StateRootTaskHash); diff --git a/neo/Persistence/CloneSnapshot.cs b/neo/Persistence/CloneSnapshot.cs index e6fb614e93..2dd0547ee1 100644 --- a/neo/Persistence/CloneSnapshot.cs +++ b/neo/Persistence/CloneSnapshot.cs @@ -21,7 +21,7 @@ internal class CloneSnapshot : Snapshot public override MetaDataCache ValidatorsCount { get; } public override MetaDataCache BlockHashIndex { get; } public override MetaDataCache HeaderHashIndex { get; } - public override MetaDataCache StateRootHashIndex { get; } + public override MetaDataCache StateRootHashIndex { get; } public CloneSnapshot(Snapshot snapshot) { diff --git a/neo/Persistence/IPersistence.cs b/neo/Persistence/IPersistence.cs index 2b77ff4d89..5643ac419d 100644 --- a/neo/Persistence/IPersistence.cs +++ b/neo/Persistence/IPersistence.cs @@ -21,6 +21,6 @@ public interface IPersistence MetaDataCache ValidatorsCount { get; } MetaDataCache BlockHashIndex { get; } MetaDataCache HeaderHashIndex { get; } - MetaDataCache StateRootHashIndex { get; } + MetaDataCache StateRootHashIndex { get; } } } diff --git a/neo/Persistence/LevelDB/DbSnapshot.cs b/neo/Persistence/LevelDB/DbSnapshot.cs index 27cb6b18b4..0813343b71 100644 --- a/neo/Persistence/LevelDB/DbSnapshot.cs +++ b/neo/Persistence/LevelDB/DbSnapshot.cs @@ -26,7 +26,7 @@ internal class DbSnapshot : Snapshot public override MetaDataCache ValidatorsCount { get; } public override MetaDataCache BlockHashIndex { get; } public override MetaDataCache HeaderHashIndex { get; } - public override MetaDataCache StateRootHashIndex { get; } + public override MetaDataCache StateRootHashIndex { get; } public DbSnapshot(DB db) { @@ -48,15 +48,7 @@ public DbSnapshot(DB db) ValidatorsCount = new DbMetaDataCache(db, options, batch, Prefixes.IX_ValidatorsCount); BlockHashIndex = new DbMetaDataCache(db, options, batch, Prefixes.IX_CurrentBlock); HeaderHashIndex = new DbMetaDataCache(db, options, batch, Prefixes.IX_CurrentHeader); - StateRootHashIndex = new DbMetaDataCache(db, options, batch, Prefixes.IX_CurrentStateRoot, - () => - { - return new HashIndexState - { - Index = 0, - Hash = UInt256.Zero, - }; - }); + StateRootHashIndex = new DbMetaDataCache(db, options, batch, Prefixes.IX_CurrentStateRoot); } public override void Commit() diff --git a/neo/Persistence/LevelDB/LevelDBStore.cs b/neo/Persistence/LevelDB/LevelDBStore.cs index b951ad95f3..23d03a47e0 100644 --- a/neo/Persistence/LevelDB/LevelDBStore.cs +++ b/neo/Persistence/LevelDB/LevelDBStore.cs @@ -117,9 +117,9 @@ public override MetaDataCache GetHeaderHashIndex() return new DbMetaDataCache(db, null, null, Prefixes.IX_CurrentHeader); } - public override MetaDataCache GetStateRootHashIndex() + public override MetaDataCache GetStateRootHashIndex() { - return new DbMetaDataCache(db, null, null, Prefixes.IX_CurrentStateRoot); + return new DbMetaDataCache(db, null, null, Prefixes.IX_CurrentStateRoot); } public override void Put(byte prefix, byte[] key, byte[] value) diff --git a/neo/Persistence/Snapshot.cs b/neo/Persistence/Snapshot.cs index a80616bcd2..4c4af70bea 100644 --- a/neo/Persistence/Snapshot.cs +++ b/neo/Persistence/Snapshot.cs @@ -27,11 +27,11 @@ public abstract class Snapshot : IDisposable, IPersistence, IScriptTable public abstract MetaDataCache ValidatorsCount { get; } public abstract MetaDataCache BlockHashIndex { get; } public abstract MetaDataCache HeaderHashIndex { get; } - public abstract MetaDataCache StateRootHashIndex { get; } + public abstract MetaDataCache StateRootHashIndex { get; } public uint Height => BlockHashIndex.Get().Index; public uint HeaderHeight => HeaderHashIndex.Get().Index; - public uint StateHeight => StateRootHashIndex.Get().Index; + public long StateHeight => StateRootHashIndex.Get().Index; public UInt256 CurrentBlockHash => BlockHashIndex.Get().Hash; public UInt256 CurrentHeaderHash => HeaderHashIndex.Get().Hash; diff --git a/neo/Persistence/Store.cs b/neo/Persistence/Store.cs index 5c93cae1fa..eb626c2aae 100644 --- a/neo/Persistence/Store.cs +++ b/neo/Persistence/Store.cs @@ -21,7 +21,7 @@ public abstract class Store : IPersistence MetaDataCache IPersistence.ValidatorsCount => GetValidatorsCount(); MetaDataCache IPersistence.BlockHashIndex => GetBlockHashIndex(); MetaDataCache IPersistence.HeaderHashIndex => GetHeaderHashIndex(); - MetaDataCache IPersistence.StateRootHashIndex => GetStateRootHashIndex(); + MetaDataCache IPersistence.StateRootHashIndex => GetStateRootHashIndex(); public abstract byte[] Get(byte prefix, byte[] key); public abstract DataCache GetBlocks(); public abstract DataCache GetTransactions(); @@ -37,7 +37,7 @@ public abstract class Store : IPersistence public abstract MetaDataCache GetValidatorsCount(); public abstract MetaDataCache GetBlockHashIndex(); public abstract MetaDataCache GetHeaderHashIndex(); - public abstract MetaDataCache GetStateRootHashIndex(); + public abstract MetaDataCache GetStateRootHashIndex(); public abstract void Put(byte prefix, byte[] key, byte[] value); public abstract void PutSync(byte prefix, byte[] key, byte[] value);