Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[StateService] Verification #470

Merged
merged 58 commits into from
Feb 1, 2021
Merged
Show file tree
Hide file tree
Changes from 57 commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
ca3fee1
add state validation
ZhangTao1596 Jan 18, 2021
73cde36
register rpc
ZhangTao1596 Jan 18, 2021
4c99958
Merge branch 'master' into state-service-validation
ZhangTao1596 Jan 18, 2021
d0a9686
Clean condition
shargon Jan 19, 2021
71b80c4
Use concurrent dictionary
shargon Jan 19, 2021
b183b04
lowercase
shargon Jan 19, 2021
7b68864
Optimize
shargon Jan 19, 2021
4d35ea4
Parallel foreach
shargon Jan 19, 2021
804d125
Clean enter
shargon Jan 19, 2021
39f9cc1
Merge branch 'master' into state-service-validation
ZhangTao1596 Jan 20, 2021
a0202bf
get wallet null check
ZhangTao1596 Jan 20, 2021
8ca0710
fix some
ZhangTao1596 Jan 20, 2021
8a578dc
rename validator to verifier
ZhangTao1596 Jan 20, 2021
2bdbb38
rename member
ZhangTao1596 Jan 20, 2021
bc33857
optimize
ZhangTao1596 Jan 20, 2021
568d330
clean verification
ZhangTao1596 Jan 20, 2021
f2371dd
optimize verification
ZhangTao1596 Jan 20, 2021
911af71
verifier null check
ZhangTao1596 Jan 20, 2021
80b584c
check verifier when start
ZhangTao1596 Jan 20, 2021
70e7201
Change string to Uri
shargon Jan 20, 2021
e18a344
add payload MaxValidUntilBlockIncrement
ZhangTao1596 Jan 21, 2021
819d44a
fix prefix and commit
ZhangTao1596 Jan 21, 2021
48c8550
add readonly
shargon Jan 21, 2021
44086db
Optimize VerificationContext
shargon Jan 22, 2021
a36eb83
Merge remote-tracking branch 'neo-project-PR187/master' into state-se…
shargon Jan 22, 2021
8f906fe
Merge branch 'master' into state-service-validation
ZhangTao1596 Jan 23, 2021
c15f5fc
Merge branch 'master' into state-service-validation
ZhangTao1596 Jan 24, 2021
4220950
recover CheckVotes
ZhangTao1596 Jan 25, 2021
a179d9b
Merge branch 'master' into state-service-validation
shargon Jan 25, 2021
fd512d4
fix ExtensiblePayload sender
ZhangTao1596 Jan 25, 2021
46b4da2
fix invalid index and index check
ZhangTao1596 Jan 25, 2021
7fcd045
Merge branch 'master' into state-service-validation
ZhangTao1596 Jan 26, 2021
f312275
delay before send vote
ZhangTao1596 Jan 26, 2021
b801d03
Merge branch 'master' into state-service-validation
superboyiii Jan 26, 2021
896135d
Merge branch 'master' into state-service-validation
ZhangTao1596 Jan 26, 2021
e324644
format
ZhangTao1596 Jan 26, 2021
4144c42
reduce burden in OnPersist
ZhangTao1596 Jan 27, 2021
0bde072
check
ZhangTao1596 Jan 27, 2021
7e1fc45
Optimize
shargon Jan 27, 2021
6caf245
Update src/StateService/Verification/VerificationService.cs
shargon Jan 27, 2021
fa50c27
fix send sig encode and optimize log
ZhangTao1596 Jan 27, 2021
74b0b30
not null client
ZhangTao1596 Jan 28, 2021
458dc7e
Merge branch 'master' into state-service-validation
shargon Jan 28, 2021
8ec0f19
timeout grow
ZhangTao1596 Jan 28, 2021
97647f2
checkvotes after send
ZhangTao1596 Jan 29, 2021
ad2ddc2
Merge branch 'master' into state-service-validation
ZhangTao1596 Jan 30, 2021
cb1bb79
exclude LedgerContract when calculate state root
ZhangTao1596 Jan 30, 2021
cb2fe33
set http timeout and call rpc async
ZhangTao1596 Jan 30, 2021
ee733d4
fix rpc client new
ZhangTao1596 Jan 30, 2021
a9e4dfb
format
erikzhang Jan 30, 2021
e83a9c3
format
erikzhang Jan 30, 2021
cc8a4bb
fix some
ZhangTao1596 Jan 31, 2021
9c40c81
concurrent
ZhangTao1596 Jan 31, 2021
f41366d
Merge branch 'master' into state-service-validation
vncoelho Jan 31, 2021
e12ca40
clear setting
ZhangTao1596 Feb 1, 2021
7c85c11
use list
ZhangTao1596 Feb 1, 2021
23175b4
Use ReadOnlySpan
erikzhang Feb 1, 2021
02e6f95
optimize
ZhangTao1596 Feb 1, 2021
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
2 changes: 1 addition & 1 deletion src/OracleService/OracleService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ public JObject SubmitOracleResponse(JArray _params)
return new JObject();
}

private static async Task SendContentAsync(string url, string content)
private static async Task SendContentAsync(Uri url, string content)
{
try
{
Expand Down
4 changes: 2 additions & 2 deletions src/OracleService/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public HttpsSettings(IConfigurationSection section)

class Settings
{
public string[] Nodes { get; }
public Uri[] Nodes { get; }
public TimeSpan MaxTaskTimeout { get; }
public bool AllowPrivateHost { get; }
public string[] AllowedContentTypes { get; }
Expand All @@ -26,7 +26,7 @@ class Settings

private Settings(IConfigurationSection section)
{
Nodes = section.GetSection("Nodes").GetChildren().Select(p => p.Get<string>()).ToArray();
Nodes = section.GetSection("Nodes").GetChildren().Select(p => new Uri(p.Get<string>(), UriKind.Absolute)).ToArray();
MaxTaskTimeout = TimeSpan.FromMilliseconds(section.GetValue("MaxTaskTimeout", 432000000));
AllowPrivateHost = section.GetValue("AllowPrivateHost", false);
AllowedContentTypes = section.GetSection("AllowedContentTypes").GetChildren().Select(p => p.Get<string>()).ToArray();
Expand Down
6 changes: 3 additions & 3 deletions src/RpcClient/RpcClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ namespace Neo.Network.RPC
public class RpcClient : IDisposable
{
private readonly HttpClient httpClient;
private readonly string baseAddress;
private readonly Uri baseAddress;

public RpcClient(string url, string rpcUser = default, string rpcPass = default)
public RpcClient(Uri url, string rpcUser = default, string rpcPass = default)
{
httpClient = new HttpClient();
baseAddress = url;
Expand All @@ -36,7 +36,7 @@ public RpcClient(string url, string rpcUser = default, string rpcPass = default)
}
}

public RpcClient(HttpClient client, string url)
public RpcClient(HttpClient client, Uri url)
{
httpClient = client;
baseAddress = url;
Expand Down
4 changes: 4 additions & 0 deletions src/StateService/Settings.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
using Microsoft.Extensions.Configuration;
using System;
using System.Linq;

namespace Neo.Plugins.StateService
{
internal class Settings
{
public string Path { get; }
public bool FullState { get; }
public Uri[] VerifierUrls { get; }

public static Settings Default { get; private set; }

private Settings(IConfigurationSection section)
{
Path = string.Format(section.GetValue("Path", "Data_MPT_{0}"), ProtocolSettings.Default.Magic.ToString("X8"));
FullState = section.GetValue("FullState", false);
VerifierUrls = section.GetSection("VerifierUrls").GetChildren().Select(p => new Uri(p.Get<string>(), UriKind.Absolute)).ToArray();
vncoelho marked this conversation as resolved.
Show resolved Hide resolved
}

public static void Load(IConfigurationSection section)
Expand Down
41 changes: 37 additions & 4 deletions src/StateService/StatePlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Neo.Persistence;
using Neo.Plugins.MPT;
using Neo.Plugins.StateService.Storage;
using Neo.Plugins.StateService.Verification;
using Neo.SmartContract;
using Neo.SmartContract.Native;
using System;
Expand All @@ -22,27 +23,59 @@ public class StatePlugin : Plugin, IPersistencePlugin
public override string Name => "StateService";
public override string Description => "Enables MPT for the node";

private IActorRef store;
internal IActorRef Store;
internal IActorRef Verifier;

protected override void Configure()
{
Settings.Load(GetConfiguration());
RpcServerPlugin.RegisterMethods(this);
}

protected override void OnPluginsLoaded()
{
store = System.ActorSystem.ActorOf(StateStore.Props(System, Settings.Default.Path));
Store = System.ActorSystem.ActorOf(StateStore.Props(System, this, Settings.Default.Path));
}

public override void Dispose()
{
base.Dispose();
System.EnsureStoped(store);
System.EnsureStoped(Store);
if (Verifier != null) System.EnsureStoped(Verifier);
}

void IPersistencePlugin.OnPersist(Block block, DataCache snapshot, IReadOnlyList<ApplicationExecuted> applicationExecutedList)
{
StateStore.Singleton.UpdateLocalStateRoot(block.Index, snapshot.GetChangeSet().Where(p => p.State != TrackState.None).ToList());
StateStore.Singleton.UpdateLocalStateRoot(block.Index, snapshot.GetChangeSet().Where(p => p.State != TrackState.None).Where(p => p.Key.Id != NativeContract.Ledger.Id).ToList());
}

[RpcMethod]
public JObject VoteStateRoot(JArray _params)
{
if (_params.Count < 3) throw new RpcException(-100, "Invalid params");
uint height = uint.Parse(_params[0].AsString());
shargon marked this conversation as resolved.
Show resolved Hide resolved
int validator_index = int.Parse(_params[1].AsString());
byte[] sig = Convert.FromBase64String(_params[2].AsString());
if (Verifier is null) throw new RpcException(-100, "Verifier not started");
Verifier.Tell(new Vote(height, validator_index, sig));
return true;
}

[ConsoleCommand("start states", Category = "StateService", Description = "Start as a state verifier if wallet is open")]
private void OnStartVerifyingState()
{
if (Verifier != null)
{
Console.WriteLine("Already started!");
return;
}
var wallet = GetService<IWalletProvider>().GetWallet();
if (wallet is null)
{
Console.WriteLine("Please open wallet first!");
return;
}
Verifier = System.ActorSystem.ActorOf(VerificationService.Props(System, wallet));
}

[ConsoleCommand("state root", Category = "StateService", Description = "Get state root by index")]
Expand Down
43 changes: 22 additions & 21 deletions src/StateService/StateService.csproj
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<PackageId>Neo.Plugins.StateService</PackageId>
<RootNamespace>Neo.Plugins</RootNamespace>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

<ItemGroup>
<None Update="StateService\config.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</None>
</ItemGroup>

<ItemGroup>
<PackageReference Include="Neo.ConsoleService" Version="1.0.0" />
<ProjectReference Include="..\RpcServer\RpcServer.csproj" />
</ItemGroup>

</Project>
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<PackageId>Neo.Plugins.StateService</PackageId>
<RootNamespace>Neo.Plugins</RootNamespace>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

<ItemGroup>
<None Update="StateService\config.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</None>
</ItemGroup>

<ItemGroup>
<PackageReference Include="Neo.ConsoleService" Version="1.0.0" />
<ProjectReference Include="..\RpcClient\RpcClient.csproj" />
<ProjectReference Include="..\RpcServer\RpcServer.csproj" />
</ItemGroup>

</Project>
4 changes: 3 additions & 1 deletion src/StateService/StateService/config.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{
"PluginConfiguration": {
"Path": "Data_MPT_{0}",
"FullState": false
"FullState": false,
"VerifierUrls": []
}
}

17 changes: 9 additions & 8 deletions src/StateService/Storage/StateSnapshot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,18 @@ public void AddLocalStateRoot(StateRoot state_root)
snapshot.Put(Keys.CurrentLocalRootIndex, BitConverter.GetBytes(state_root.Index));
}

public uint CurrentLocalRootIndex()
public uint? CurrentLocalRootIndex()
{
var bytes = snapshot.TryGet(Keys.CurrentLocalRootIndex);
if (bytes is null) return uint.MaxValue;
if (bytes is null) return null;
return BitConverter.ToUInt32(bytes);
}

public UInt256 CurrentLocalRootHash()
{
var index = CurrentLocalRootIndex();
if (index == uint.MaxValue) return null;
return GetStateRoot(index)?.RootHash;
if (index is null) return null;
return GetStateRoot((uint)index)?.RootHash;
}

public void AddValidatedStateRoot(StateRoot state_root)
Expand All @@ -50,25 +50,26 @@ public void AddValidatedStateRoot(StateRoot state_root)
snapshot.Put(Keys.CurrentValidatedRootIndex, BitConverter.GetBytes(state_root.Index));
}

public uint CurrentValidatedRootIndex()
public uint? CurrentValidatedRootIndex()
{
var bytes = snapshot.TryGet(Keys.CurrentValidatedRootIndex);
if (bytes is null) return uint.MaxValue;
if (bytes is null) return null;
return BitConverter.ToUInt32(bytes);
}

public UInt256 CurrentValidatedRootHash()
{
var index = CurrentLocalRootIndex();
if (index == uint.MaxValue) return null;
var state_root = GetStateRoot(index);
if (index is null) return null;
var state_root = GetStateRoot((uint)index);
if (state_root is null || state_root.Witness is null)
throw new InvalidOperationException(nameof(CurrentValidatedRootHash) + " could not get validated state root");
return state_root.RootHash;
}

public void Commit()
{
Trie.Commit();
snapshot.Commit();
}

Expand Down
24 changes: 16 additions & 8 deletions src/StateService/Storage/StateStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Neo.Network.P2P.Payloads;
using Neo.Persistence;
using Neo.Plugins.MPT;
using Neo.Plugins.StateService.Verification;
using Neo.SmartContract;
using System;
using System.Collections.Generic;
Expand All @@ -14,13 +15,14 @@ namespace Neo.Plugins.StateService.Storage
class StateStore : UntypedActor
{
private readonly NeoSystem core;
private readonly StatePlugin system;
private readonly IStore store;
private const int MaxCacheCount = 100;
private readonly Dictionary<uint, StateRoot> cache = new Dictionary<uint, StateRoot>();
private StateSnapshot currentSnapshot;
public UInt256 CurrentLocalRootHash => currentSnapshot.CurrentLocalRootHash();
public uint LocalRootIndex => currentSnapshot.CurrentLocalRootIndex();
public uint ValidatedRootIndex => currentSnapshot.CurrentValidatedRootIndex();
public uint? LocalRootIndex => currentSnapshot.CurrentLocalRootIndex();
public uint? ValidatedRootIndex => currentSnapshot.CurrentValidatedRootIndex();

private static StateStore singleton;
public static StateStore Singleton
Expand All @@ -32,10 +34,11 @@ public static StateStore Singleton
}
}

public StateStore(NeoSystem core, string path)
public StateStore(NeoSystem core, StatePlugin system, string path)
{
if (singleton != null) throw new InvalidOperationException(nameof(StateStore));
this.core = core;
this.system = system;
this.store = core.LoadStore(path);
singleton = this;
core.ActorSystem.EventStream.Subscribe(Self, typeof(Blockchain.RelayResult));
Expand Down Expand Up @@ -63,6 +66,9 @@ protected override void OnReceive(object message)
{
switch (message)
{
case StateRoot state_root:
OnNewStateRoot(state_root);
break;
case Blockchain.RelayResult rr:
if (rr.Result == VerifyResult.Succeed && rr.Inventory is ExtensiblePayload payload && payload.Category == StatePlugin.StatePayloadCategory)
OnStatePayload(payload);
Expand Down Expand Up @@ -91,7 +97,8 @@ private void OnStatePayload(ExtensiblePayload payload)
private bool OnNewStateRoot(StateRoot state_root)
{
if (state_root?.Witness is null) return false;
if (state_root.Index <= ValidatedRootIndex) return false;
if (ValidatedRootIndex != null && state_root.Index <= ValidatedRootIndex) return false;
if (LocalRootIndex is null) throw new InvalidOperationException(nameof(StateStore) + " could not get local root index");
if (LocalRootIndex < state_root.Index && state_root.Index < LocalRootIndex + MaxCacheCount)
{
cache.Add(state_root.Index, state_root);
Expand All @@ -106,7 +113,7 @@ private bool OnNewStateRoot(StateRoot state_root)
state_snapshot.AddValidatedStateRoot(state_root);
state_snapshot.Commit();
UpdateCurrentSnapshot();
//Tell validation service
system.Verifier?.Tell(new VerificationService.ValidatedRootPersisted { Index = state_root.Index });
return true;
}

Expand Down Expand Up @@ -138,6 +145,7 @@ public void UpdateLocalStateRoot(uint height, List<DataCache.Trackable> change_s
state_snapshot.AddLocalStateRoot(state_root);
state_snapshot.Commit();
UpdateCurrentSnapshot();
system.Verifier?.Tell(new VerificationService.BlockPersisted { Index = height });
CheckValidatedStateRoot(height);
}

Expand All @@ -146,7 +154,7 @@ private void CheckValidatedStateRoot(uint index)
if (cache.TryGetValue(index, out StateRoot state_root))
{
cache.Remove(index);
OnNewStateRoot(state_root);
Self.Tell(state_root);
}
}

Expand All @@ -160,9 +168,9 @@ protected override void PostStop()
base.PostStop();
}

public static Props Props(NeoSystem core, string path)
public static Props Props(NeoSystem core, StatePlugin system, string path)
{
return Akka.Actor.Props.Create(() => new StateStore(core, path));
return Akka.Actor.Props.Create(() => new StateStore(core, system, path));
}
}
}
Loading