From b3be4189a8ce95928c53b7474a350f2bf42e2a97 Mon Sep 17 00:00:00 2001 From: Owen Zhang <38493437+superboyiii@users.noreply.github.com> Date: Sat, 6 Mar 2021 15:47:11 +0800 Subject: [PATCH 01/30] update to Neo v3.0.0-CI01234 (#538) * update to Neo v3.0.0-CI01232 * fix UT * fix --- src/Directory.Build.props | 2 +- tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index c6f7ea738..49de2f64a 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -15,7 +15,7 @@ - + diff --git a/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs b/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs index 8fac2e42b..f6dd24c07 100644 --- a/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs +++ b/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs @@ -171,8 +171,8 @@ await txManager Assert.AreEqual(100, tx.SystemFee); // duplicate sign should not add new witness - await txManager.AddSignature(keyPair1).SignAsync(); - Assert.AreEqual(1, txManager.Tx.Witnesses.Length); + await ThrowsAsync(async () => await txManager.AddSignature(keyPair1).SignAsync()); + Assert.AreEqual(null, txManager.Tx.Witnesses); // throw exception when the KeyPair is wrong await ThrowsAsync(async () => await txManager.AddSignature(keyPair2).SignAsync()); From 209b6748ac8a5f83bf3a51dd2664e483469d84db Mon Sep 17 00:00:00 2001 From: Harry Pierson Date: Sun, 7 Mar 2021 02:56:48 -0800 Subject: [PATCH 02/30] public RpcServerSettings (#539) * public RpcServerSettings * dotnet format Co-authored-by: Shargon --- src/RpcServer/RpcServer.cs | 2 +- src/RpcServer/Settings.cs | 70 +++++++++++++++++++++++--------------- 2 files changed, 43 insertions(+), 29 deletions(-) diff --git a/src/RpcServer/RpcServer.cs b/src/RpcServer/RpcServer.cs index 584e6252e..9cd76a79e 100644 --- a/src/RpcServer/RpcServer.cs +++ b/src/RpcServer/RpcServer.cs @@ -30,7 +30,7 @@ public partial class RpcServer : IDisposable private readonly NeoSystem system; private readonly LocalNode localNode; - internal RpcServer(NeoSystem system, RpcServerSettings settings) + public RpcServer(NeoSystem system, RpcServerSettings settings) { this.system = system; this.settings = settings; diff --git a/src/RpcServer/Settings.cs b/src/RpcServer/Settings.cs index 32da467cd..5ea890d8d 100644 --- a/src/RpcServer/Settings.cs +++ b/src/RpcServer/Settings.cs @@ -1,5 +1,6 @@ using Microsoft.Extensions.Configuration; using Neo.SmartContract.Native; +using System; using System.Collections.Generic; using System.Linq; using System.Net; @@ -12,39 +13,52 @@ class Settings public Settings(IConfigurationSection section) { - Servers = section.GetSection(nameof(Servers)).GetChildren().Select(p => new RpcServerSettings(p)).ToArray(); + Servers = section.GetSection(nameof(Servers)).GetChildren().Select(p => RpcServerSettings.Load(p)).ToArray(); } } - class RpcServerSettings + public record RpcServerSettings { - public uint Network { get; } - public IPAddress BindAddress { get; } - public ushort Port { get; } - public string SslCert { get; } - public string SslCertPassword { get; } - public string[] TrustedAuthorities { get; } - public int MaxConcurrentConnections { get; } - public string RpcUser { get; } - public string RpcPass { get; } - public long MaxGasInvoke { get; } - public long MaxFee { get; } - public string[] DisabledMethods { get; } + public uint Network { get; init; } + public IPAddress BindAddress { get; init; } + public ushort Port { get; init; } + public string SslCert { get; init; } + public string SslCertPassword { get; init; } + public string[] TrustedAuthorities { get; init; } + public int MaxConcurrentConnections { get; init; } + public string RpcUser { get; init; } + public string RpcPass { get; init; } + public long MaxGasInvoke { get; init; } + public long MaxFee { get; init; } + public string[] DisabledMethods { get; init; } - public RpcServerSettings(IConfigurationSection section) + public static RpcServerSettings Default { get; } = new RpcServerSettings { - this.Network = section.GetValue("Network", 5195086u); - this.BindAddress = IPAddress.Parse(section.GetSection("BindAddress").Value); - this.Port = ushort.Parse(section.GetSection("Port").Value); - this.SslCert = section.GetSection("SslCert").Value; - this.SslCertPassword = section.GetSection("SslCertPassword").Value; - this.TrustedAuthorities = section.GetSection("TrustedAuthorities").GetChildren().Select(p => p.Get()).ToArray(); - this.RpcUser = section.GetSection("RpcUser").Value; - this.RpcPass = section.GetSection("RpcPass").Value; - this.MaxGasInvoke = (long)new BigDecimal(section.GetValue("MaxGasInvoke", 10M), NativeContract.GAS.Decimals).Value; - this.MaxFee = (long)new BigDecimal(section.GetValue("MaxFee", 0.1M), NativeContract.GAS.Decimals).Value; - this.DisabledMethods = section.GetSection("DisabledMethods").GetChildren().Select(p => p.Get()).ToArray(); - this.MaxConcurrentConnections = section.GetValue("MaxConcurrentConnections", 40); - } + Network = 5195086u, + BindAddress = IPAddress.None, + SslCert = string.Empty, + SslCertPassword = string.Empty, + MaxGasInvoke = (long)new BigDecimal(10M, NativeContract.GAS.Decimals).Value, + MaxFee = (long)new BigDecimal(0.1M, NativeContract.GAS.Decimals).Value, + TrustedAuthorities = Array.Empty(), + DisabledMethods = Array.Empty(), + MaxConcurrentConnections = 40, + }; + + public static RpcServerSettings Load(IConfigurationSection section) => new RpcServerSettings + { + Network = section.GetValue("Network", Default.Network), + BindAddress = IPAddress.Parse(section.GetSection("BindAddress").Value), + Port = ushort.Parse(section.GetSection("Port").Value), + SslCert = section.GetSection("SslCert").Value, + SslCertPassword = section.GetSection("SslCertPassword").Value, + TrustedAuthorities = section.GetSection("TrustedAuthorities").GetChildren().Select(p => p.Get()).ToArray(), + RpcUser = section.GetSection("RpcUser").Value, + RpcPass = section.GetSection("RpcPass").Value, + MaxGasInvoke = (long)new BigDecimal(section.GetValue("MaxGasInvoke", Default.MaxGasInvoke), NativeContract.GAS.Decimals).Value, + MaxFee = (long)new BigDecimal(section.GetValue("MaxFee", Default.MaxFee), NativeContract.GAS.Decimals).Value, + DisabledMethods = section.GetSection("DisabledMethods").GetChildren().Select(p => p.Get()).ToArray(), + MaxConcurrentConnections = section.GetValue("MaxConcurrentConnections", Default.MaxConcurrentConnections), + }; } } From 0b69cf8d22d0e0f0732bdae1e706fdbe44a5fa77 Mon Sep 17 00:00:00 2001 From: cloud8little <34291844+cloud8little@users.noreply.github.com> Date: Mon, 8 Mar 2021 15:40:22 +0800 Subject: [PATCH 03/30] Fix State Autoverify when Oracle Service Unavailable (#540) Co-authored-by: Shargon Co-authored-by: Owen Zhang <38493437+superboyiii@users.noreply.github.com> --- src/OracleService/OracleService.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/OracleService/OracleService.cs b/src/OracleService/OracleService.cs index 905bdf34a..a12b22b23 100644 --- a/src/OracleService/OracleService.cs +++ b/src/OracleService/OracleService.cs @@ -108,8 +108,16 @@ public void Start(Wallet wallet) Console.WriteLine("Please open wallet first!"); return; } - if (!CheckOracleAvaiblable(System.StoreView, out ECPoint[] oracles)) throw new ArgumentException("The oracle service is unavailable"); - if (!CheckOracleAccount(wallet, oracles)) throw new ArgumentException("There is no oracle account in wallet"); + if (!CheckOracleAvaiblable(System.StoreView, out ECPoint[] oracles)) + { + Console.WriteLine("The oracle service is unavailable"); + return; + } + if (!CheckOracleAccount(wallet, oracles)) + { + Console.WriteLine("There is no oracle account in wallet"); + return; + } this.wallet = wallet; started = true; From 68da90f1d55ad9e2f22bc28bbf23551a82db7fb8 Mon Sep 17 00:00:00 2001 From: doubiliu Date: Tue, 9 Mar 2021 10:22:15 +0800 Subject: [PATCH 04/30] Integrate NeoFS into oracle module (#518) * Integrate NeoFS into oracle module * Rename * Fix bug * Fix bug * Fix UT * Clean using * Optimize * Reorder using * change to base64 * change to random * Fix bug * Rename * change to single node * Remove AttachWallet * Rename * Remove empty line * Update OracleNeoFSProtocol.cs * Fix bug * fix bug * neofs request timeout * url check * Update OracleNeoFSProtocol.cs * Update config.json * apply timeout * Fix memory leak * async * update neofs api * remove neofs request host check * Fix bug of URL encode * Fix format * add default salt, format * Return JSON string of ObjectHeader * Optimize Co-authored-by: Shargon Co-authored-by: Erik Zhang Co-authored-by: ZhangTao1596 --- src/OracleService/OracleService.cs | 7 +- src/OracleService/OracleService.csproj | 1 + src/OracleService/OracleService/config.json | 4 + .../Protocols/OracleNeoFSProtocol.cs | 121 ++++++++++++++++++ src/OracleService/Settings.cs | 14 ++ 5 files changed, 143 insertions(+), 4 deletions(-) create mode 100644 src/OracleService/Protocols/OracleNeoFSProtocol.cs diff --git a/src/OracleService/OracleService.cs b/src/OracleService/OracleService.cs index a12b22b23..4afb0e67d 100644 --- a/src/OracleService/OracleService.cs +++ b/src/OracleService/OracleService.cs @@ -43,10 +43,7 @@ public class OracleService : Plugin, IPersistencePlugin private int counter; private NeoSystem System; - private static readonly IReadOnlyDictionary protocols = new Dictionary - { - ["https"] = new OracleHttpsProtocol() - }; + private readonly Dictionary protocols = new Dictionary(); public override string Description => "Built-in oracle plugin"; @@ -120,6 +117,8 @@ public void Start(Wallet wallet) } this.wallet = wallet; + protocols["https"] = new OracleHttpsProtocol(); + protocols["neofs"] = new OracleNeoFSProtocol(wallet, oracles); started = true; timer = new Timer(OnTimer, null, RefreshInterval, Timeout.Infinite); diff --git a/src/OracleService/OracleService.csproj b/src/OracleService/OracleService.csproj index ac01a71bb..aa6cc6d21 100644 --- a/src/OracleService/OracleService.csproj +++ b/src/OracleService/OracleService.csproj @@ -6,6 +6,7 @@ + diff --git a/src/OracleService/OracleService/config.json b/src/OracleService/OracleService/config.json index 76e862d29..83f690ac5 100644 --- a/src/OracleService/OracleService/config.json +++ b/src/OracleService/OracleService/config.json @@ -8,6 +8,10 @@ "Https": { "Timeout": 5000 }, + "NeoFS": { + "EndPoint": "127.0.0.1:8080", + "Timeout": 15000 + }, "AutoStart": false } } diff --git a/src/OracleService/Protocols/OracleNeoFSProtocol.cs b/src/OracleService/Protocols/OracleNeoFSProtocol.cs new file mode 100644 index 000000000..5db1324fb --- /dev/null +++ b/src/OracleService/Protocols/OracleNeoFSProtocol.cs @@ -0,0 +1,121 @@ +using Neo.Cryptography.ECC; +using Neo.FileSystem.API.Client; +using Neo.FileSystem.API.Client.ObjectParams; +using Neo.FileSystem.API.Cryptography; +using Neo.FileSystem.API.Refs; +using Neo.Network.P2P.Payloads; +using Neo.Wallets; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using System.Web; +using Object = Neo.FileSystem.API.Object.Object; +using Range = Neo.FileSystem.API.Object.Range; + +namespace Neo.Plugins +{ + class OracleNeoFSProtocol : IOracleProtocol + { + private readonly System.Security.Cryptography.ECDsa privateKey; + + public OracleNeoFSProtocol(Wallet wallet, ECPoint[] oracles) + { + byte[] key = oracles.Select(p => wallet.GetAccount(p)).Where(p => p is not null && p.HasKey && !p.Lock).FirstOrDefault().GetKey().PrivateKey; + privateKey = key.LoadPrivateKey(); + } + + public void Configure() + { + } + + public void Dispose() + { + privateKey.Dispose(); + } + + public async Task<(OracleResponseCode, string)> ProcessAsync(Uri uri, CancellationToken cancellation) + { + Utility.Log(nameof(OracleNeoFSProtocol), LogLevel.Debug, $"Request: {uri.AbsoluteUri}"); + try + { + byte[] res = await GetAsync(uri, Settings.Default.NeoFS.EndPoint, cancellation); + Utility.Log(nameof(OracleNeoFSProtocol), LogLevel.Debug, $"NeoFS result: {res.ToHexString()}"); + return (OracleResponseCode.Success, Convert.ToBase64String(res)); + } + catch (Exception e) + { + Utility.Log(nameof(OracleNeoFSProtocol), LogLevel.Debug, $"NeoFS result: error,{e.Message}"); + return (OracleResponseCode.Error, null); + } + } + + private Task GetAsync(Uri uri, string host, CancellationToken cancellation) + { + string[] ps = uri.AbsolutePath.Split("/"); + if (ps.Length < 2) throw new FormatException("Invalid neofs url"); + ContainerID containerID = ContainerID.FromBase58String(ps[0]); + ObjectID objectID = ObjectID.FromBase58String(ps[1]); + Address objectAddr = new() + { + ContainerId = containerID, + ObjectId = objectID + }; + Client client = new(privateKey, host); + var tokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellation); + tokenSource.CancelAfter(Settings.Default.NeoFS.Timeout); + if (ps.Length == 2) + return GetPayloadAsync(client, objectAddr, tokenSource.Token); + return ps[2] switch + { + "range" => GetRangeAsync(client, objectAddr, ps.Skip(3).ToArray(), tokenSource.Token), + "header" => GetHeaderAsync(client, objectAddr, tokenSource.Token), + "hash" => GetHashAsync(client, objectAddr, ps.Skip(3).ToArray(), tokenSource.Token), + _ => throw new Exception("invalid command") + }; + } + + private static async Task GetPayloadAsync(Client client, Address addr, CancellationToken cancellation) + { + Object obj = await client.GetObject(cancellation, new GetObjectParams() { Address = addr }, new CallOptions { Ttl = 2 }); + return obj.Payload.ToByteArray(); + } + + private static Task GetRangeAsync(Client client, Address addr, string[] ps, CancellationToken cancellation) + { + if (ps.Length == 0) throw new FormatException("missing object range (expected 'Offset|Length')"); + Range range = ParseRange(ps[0]); + return client.GetObjectPayloadRangeData(cancellation, new RangeDataParams() { Address = addr, Range = range }, new CallOptions { Ttl = 2 }); + } + + private static async Task GetHeaderAsync(Client client, Address addr, CancellationToken cancellation) + { + var obj = await client.GetObjectHeader(cancellation, new ObjectHeaderParams() { Address = addr }, new CallOptions { Ttl = 2 }); + return Utility.StrictUTF8.GetBytes(obj.ToString()); + } + + private static async Task GetHashAsync(Client client, Address addr, string[] ps, CancellationToken cancellation) + { + if (ps.Length == 0 || ps[0] == "") + { + Object obj = await client.GetObjectHeader(cancellation, new ObjectHeaderParams() { Address = addr }, new CallOptions { Ttl = 2 }); + return obj.PayloadChecksum.Sum.ToByteArray(); + } + Range range = ParseRange(ps[0]); + List hashes = await client.GetObjectPayloadRangeHash(cancellation, new RangeChecksumParams() { Address = addr, Ranges = new List() { range }, Type = ChecksumType.Sha256, Salt = Array.Empty() }, new CallOptions { Ttl = 2 }); + if (hashes.Count == 0) throw new Exception("empty response, object range is invalid (expected 'Offset|Length')"); + return hashes[0]; + } + + private static Range ParseRange(string s) + { + string url = HttpUtility.UrlDecode(s); + int sepIndex = url.IndexOf("|"); + if (sepIndex < 0) throw new Exception("object range is invalid (expected 'Offset|Length')"); + ulong offset = ulong.Parse(url[..sepIndex]); + ulong length = ulong.Parse(url[(sepIndex + 1)..]); + return new Range() { Offset = offset, Length = length }; + } + } +} diff --git a/src/OracleService/Settings.cs b/src/OracleService/Settings.cs index fe705e026..600540be2 100644 --- a/src/OracleService/Settings.cs +++ b/src/OracleService/Settings.cs @@ -14,6 +14,18 @@ public HttpsSettings(IConfigurationSection section) } } + class NeoFSSettings + { + public string EndPoint { get; } + public TimeSpan Timeout { get; } + + public NeoFSSettings(IConfigurationSection section) + { + EndPoint = section.GetValue("EndPoint", "127.0.0.1:8080"); + Timeout = TimeSpan.FromMilliseconds(section.GetValue("Timeout", 15000)); + } + } + class Settings { public uint Network { get; } @@ -22,6 +34,7 @@ class Settings public bool AllowPrivateHost { get; } public string[] AllowedContentTypes { get; } public HttpsSettings Https { get; } + public NeoFSSettings NeoFS { get; } public bool AutoStart { get; } public static Settings Default { get; private set; } @@ -34,6 +47,7 @@ private Settings(IConfigurationSection section) AllowPrivateHost = section.GetValue("AllowPrivateHost", false); AllowedContentTypes = section.GetSection("AllowedContentTypes").GetChildren().Select(p => p.Get()).ToArray(); Https = new HttpsSettings(section.GetSection("Https")); + NeoFS = new NeoFSSettings(section.GetSection("NeoFS")); AutoStart = section.GetValue("AutoStart", false); } From b54fb54c38b68365e724699d723852d517c46dec Mon Sep 17 00:00:00 2001 From: cloud8little <34291844+cloud8little@users.noreply.github.com> Date: Wed, 10 Mar 2021 18:31:00 +0800 Subject: [PATCH 05/30] add settings to invokecontractverify (#546) --- src/RpcServer/RpcServer.Wallet.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RpcServer/RpcServer.Wallet.cs b/src/RpcServer/RpcServer.Wallet.cs index 196bbe9b6..7c75e628f 100644 --- a/src/RpcServer/RpcServer.Wallet.cs +++ b/src/RpcServer/RpcServer.Wallet.cs @@ -359,7 +359,7 @@ private JObject GetVerificationResult(UInt160 scriptHash, ContractParameter[] ar wallet.Sign(context); tx.Witnesses = context.Completed ? context.GetWitnesses() : null; - using ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot.CreateSnapshot()); + using ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot.CreateSnapshot(), settings: system.Settings); engine.LoadScript(new ScriptBuilder().EmitDynamicCall(scriptHash, methodName, args).ToArray(), rvcount: 1); JObject json = new JObject(); From f6dd4220114a0edd162a6fa804c19204a7abba7a Mon Sep 17 00:00:00 2001 From: Erik Zhang Date: Thu, 11 Mar 2021 16:48:21 +0800 Subject: [PATCH 06/30] Fix RpcNep17Tracker (#549) --- src/RpcNep17Tracker/RpcNep17Tracker.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/RpcNep17Tracker/RpcNep17Tracker.cs b/src/RpcNep17Tracker/RpcNep17Tracker.cs index b4d34f0d8..8b7ef2ea6 100644 --- a/src/RpcNep17Tracker/RpcNep17Tracker.cs +++ b/src/RpcNep17Tracker/RpcNep17Tracker.cs @@ -122,9 +122,8 @@ private void HandleNotification(DataCache snapshot, IVerifiable scriptContainer, VM.Types.Array stateItems, Dictionary nep17BalancesChanged, ref ushort transferIndex) { - if (stateItems.Count == 0) return; if (eventName != "Transfer") return; - if (stateItems.Count < 3) return; + if (stateItems.Count != 3) return; if (!(stateItems[0].IsNull) && !(stateItems[0] is VM.Types.ByteString)) return; From 603ecec356d4ec675023501cb59c24d1e4ded73b Mon Sep 17 00:00:00 2001 From: Owen Zhang <38493437+superboyiii@users.noreply.github.com> Date: Fri, 12 Mar 2021 16:01:11 +0800 Subject: [PATCH 07/30] Update Neo to 3.0.0-CI01239 (#551) 3.0.0-CI01239 --- src/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 49de2f64a..a4d2a41af 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -15,7 +15,7 @@ - + From adffb961c657057402277cdcbc2e56e5c28b932a Mon Sep 17 00:00:00 2001 From: ZhangTao Date: Mon, 15 Mar 2021 10:31:10 +0800 Subject: [PATCH 08/30] [DBFTPlugin] Dbft constructor (#545) * provide settings in dbft constructor * remove static * rename * Erik's feedback * original RecoveryMessage.Deserialize with extra check * Remove Settings.Default * message type read once * Harry's suggestion * Revert dummy changes * this * add verify * Clean enter * Remove () * Update * use byte.MaxValue * Remove cast Co-authored-by: Shargon Co-authored-by: Erik Zhang --- src/DBFTPlugin/ConsensusContext.cs | 58 ++++++++++--------- src/DBFTPlugin/ConsensusMessage.cs | 7 ++- src/DBFTPlugin/ConsensusService.cs | 58 ++++++++++--------- src/DBFTPlugin/DBFTPlugin.cs | 20 ++++--- src/DBFTPlugin/PrepareRequest.cs | 11 ++-- src/DBFTPlugin/PrepareResponse.cs | 5 +- ...ecoveryMessage.ChangeViewPayloadCompact.cs | 3 - .../RecoveryMessage.CommitPayloadCompact.cs | 2 - ...coveryMessage.PreparationPayloadCompact.cs | 3 - src/DBFTPlugin/RecoveryMessage.cs | 27 ++++++--- src/DBFTPlugin/Settings.cs | 11 +--- 11 files changed, 106 insertions(+), 99 deletions(-) diff --git a/src/DBFTPlugin/ConsensusContext.cs b/src/DBFTPlugin/ConsensusContext.cs index aa36d48f2..5d2c60c57 100644 --- a/src/DBFTPlugin/ConsensusContext.cs +++ b/src/DBFTPlugin/ConsensusContext.cs @@ -41,11 +41,13 @@ public class ConsensusContext : IDisposable, ISerializable /// /// Store all verified unsorted transactions' senders' fee currently in the consensus context. /// - public TransactionVerificationContext VerificationContext = new TransactionVerificationContext(); + public TransactionVerificationContext VerificationContext = new(); public SnapshotCache Snapshot { get; private set; } private KeyPair keyPair; private int _witnessSize; + private readonly NeoSystem neoSystem; + private readonly Settings dbftSettings; private readonly Wallet wallet; private readonly IStore store; private Dictionary cachedMessages; @@ -94,17 +96,19 @@ public bool ValidatorsChanged public int Size => throw new NotImplementedException(); - public ConsensusContext(Wallet wallet, IStore store) + public ConsensusContext(NeoSystem neoSystem, Settings settings, Wallet wallet) { this.wallet = wallet; - this.store = store; + this.neoSystem = neoSystem; + this.dbftSettings = settings; + this.store = neoSystem.LoadStore(settings.RecoveryLogs); } public Block CreateBlock() { EnsureHeader(); Contract contract = Contract.CreateMultiSigContract(M, Validators); - ContractParametersContext sc = new ContractParametersContext(DBFTPlugin.System.StoreView, Block.Header); + ContractParametersContext sc = new ContractParametersContext(neoSystem.StoreView, Block.Header); for (int i = 0, j = 0; i < Validators.Length && j < M; i++) { if (GetMessage(CommitPayloads[i])?.ViewNumber != ViewNumber) continue; @@ -148,10 +152,10 @@ public void Deserialize(BinaryReader reader) ViewNumber = reader.ReadByte(); TransactionHashes = reader.ReadSerializableArray(ushort.MaxValue); Transaction[] transactions = reader.ReadSerializableArray(ushort.MaxValue); - PreparationPayloads = reader.ReadNullableArray(DBFTPlugin.System.Settings.ValidatorsCount); - CommitPayloads = reader.ReadNullableArray(DBFTPlugin.System.Settings.ValidatorsCount); - ChangeViewPayloads = reader.ReadNullableArray(DBFTPlugin.System.Settings.ValidatorsCount); - LastChangeViewPayloads = reader.ReadNullableArray(DBFTPlugin.System.Settings.ValidatorsCount); + PreparationPayloads = reader.ReadNullableArray(neoSystem.Settings.ValidatorsCount); + CommitPayloads = reader.ReadNullableArray(neoSystem.Settings.ValidatorsCount); + ChangeViewPayloads = reader.ReadNullableArray(neoSystem.Settings.ValidatorsCount); + LastChangeViewPayloads = reader.ReadNullableArray(neoSystem.Settings.ValidatorsCount); if (TransactionHashes.Length == 0 && !RequestSentOrReceived) TransactionHashes = null; Transactions = transactions.Length == 0 && !RequestSentOrReceived ? null : transactions.ToDictionary(p => p.Hash); @@ -265,7 +269,7 @@ public ExtensiblePayload MakeCommit() { return CommitPayloads[MyIndex] ?? (CommitPayloads[MyIndex] = MakeSignedPayload(new Commit { - Signature = EnsureHeader().Sign(keyPair, DBFTPlugin.System.Settings.Magic) + Signature = EnsureHeader().Sign(keyPair, neoSystem.Settings.Magic) })); } @@ -284,7 +288,7 @@ private void SignPayload(ExtensiblePayload payload) ContractParametersContext sc; try { - sc = new ContractParametersContext(DBFTPlugin.System.StoreView, payload); + sc = new ContractParametersContext(neoSystem.StoreView, payload); wallet.Sign(sc); } catch (InvalidOperationException) @@ -335,7 +339,7 @@ internal int GetExpectedBlockSizeWithoutTransactions(int expectedTransactions) /// Ordered transactions internal void EnsureMaxBlockLimitation(IEnumerable txs) { - uint maxTransactionsPerBlock = DBFTPlugin.System.Settings.MaxTransactionsPerBlock; + uint maxTransactionsPerBlock = neoSystem.Settings.MaxTransactionsPerBlock; // Limit Speaker proposal to the limit `MaxTransactionsPerBlock` or all available transactions of the mempool txs = txs.Take((int)maxTransactionsPerBlock); @@ -352,11 +356,11 @@ internal void EnsureMaxBlockLimitation(IEnumerable txs) { // Check if maximum block size has been already exceeded with the current selected set blockSize += tx.Size; - if (blockSize > Settings.Default.MaxBlockSize) break; + if (blockSize > dbftSettings.MaxBlockSize) break; // Check if maximum block system fee has been already exceeded with the current selected set blockSystemFee += tx.SystemFee; - if (blockSystemFee > Settings.Default.MaxBlockSystemFee) break; + if (blockSystemFee > dbftSettings.MaxBlockSystemFee) break; hashes.Add(tx.Hash); Transactions.Add(tx.Hash, tx); @@ -368,7 +372,7 @@ internal void EnsureMaxBlockLimitation(IEnumerable txs) public ExtensiblePayload MakePrepareRequest() { - EnsureMaxBlockLimitation(DBFTPlugin.System.MemPool.GetSortedVerifiedTransactions()); + EnsureMaxBlockLimitation(neoSystem.MemPool.GetSortedVerifiedTransactions()); Block.Header.Timestamp = Math.Max(TimeProvider.Current.UtcNow.ToTimestampMS(), PrevHeader.Timestamp + 1); return PreparationPayloads[MyIndex] = MakeSignedPayload(new PrepareRequest @@ -403,16 +407,16 @@ public ExtensiblePayload MakeRecoveryMessage() TransactionHashes = TransactionHashes }; } - return MakeSignedPayload(new RecoveryMessage() + return MakeSignedPayload(new RecoveryMessage { - ChangeViewMessages = LastChangeViewPayloads.Where(p => p != null).Select(p => GetChangeViewPayloadCompact(p)).Take(M).ToDictionary(p => (int)p.ValidatorIndex), + ChangeViewMessages = LastChangeViewPayloads.Where(p => p != null).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(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)).ToDictionary(p => (int)p.ValidatorIndex), + PreparationMessages = PreparationPayloads.Where(p => p != null).Select(p => GetPreparationPayloadCompact(p)).ToDictionary(p => p.ValidatorIndex), CommitMessages = CommitSent - ? CommitPayloads.Where(p => p != null).Select(p => GetCommitPayloadCompact(p)).ToDictionary(p => (int)p.ValidatorIndex) - : new Dictionary() + ? CommitPayloads.Where(p => p != null).Select(p => GetCommitPayloadCompact(p)).ToDictionary(p => p.ValidatorIndex) + : new Dictionary() }); } @@ -429,7 +433,7 @@ public void Reset(byte viewNumber) if (viewNumber == 0) { Snapshot?.Dispose(); - Snapshot = DBFTPlugin.System.GetSnapshot(); + Snapshot = neoSystem.GetSnapshot(); uint height = NativeContract.Ledger.CurrentIndex(Snapshot); Block = new Block { @@ -438,17 +442,17 @@ public void Reset(byte viewNumber) PrevHash = NativeContract.Ledger.CurrentHash(Snapshot), Index = height + 1, NextConsensus = Contract.GetBFTAddress( - NeoToken.ShouldRefreshCommittee(height + 1, DBFTPlugin.System.Settings.CommitteeMembersCount) ? - NativeContract.NEO.ComputeNextBlockValidators(Snapshot, DBFTPlugin.System.Settings) : - NativeContract.NEO.GetNextBlockValidators(Snapshot, DBFTPlugin.System.Settings.ValidatorsCount)) + NeoToken.ShouldRefreshCommittee(height + 1, neoSystem.Settings.CommitteeMembersCount) ? + NativeContract.NEO.ComputeNextBlockValidators(Snapshot, neoSystem.Settings) : + NativeContract.NEO.GetNextBlockValidators(Snapshot, neoSystem.Settings.ValidatorsCount)) } }; var pv = Validators; - Validators = NativeContract.NEO.GetNextBlockValidators(Snapshot, DBFTPlugin.System.Settings.ValidatorsCount); + Validators = NativeContract.NEO.GetNextBlockValidators(Snapshot, neoSystem.Settings.ValidatorsCount); if (_witnessSize == 0 || (pv != null && pv.Length != Validators.Length)) { // Compute the expected size of the witness - using (ScriptBuilder sb = new ScriptBuilder()) + using (ScriptBuilder sb = new()) { for (int x = 0; x < M; x++) { @@ -519,8 +523,8 @@ public void Serialize(BinaryWriter writer) writer.Write(Block.PrimaryIndex); writer.Write(Block.NextConsensus ?? UInt160.Zero); writer.Write(ViewNumber); - writer.Write(TransactionHashes ?? new UInt256[0]); - writer.Write(Transactions?.Values.ToArray() ?? new Transaction[0]); + writer.Write(TransactionHashes ?? Array.Empty()); + writer.Write(Transactions?.Values.ToArray() ?? Array.Empty()); writer.WriteNullableArray(PreparationPayloads); writer.WriteNullableArray(CommitPayloads); writer.WriteNullableArray(ChangeViewPayloads); diff --git a/src/DBFTPlugin/ConsensusMessage.cs b/src/DBFTPlugin/ConsensusMessage.cs index 2cf230f3f..3f4d06371 100644 --- a/src/DBFTPlugin/ConsensusMessage.cs +++ b/src/DBFTPlugin/ConsensusMessage.cs @@ -30,8 +30,6 @@ public virtual void Deserialize(BinaryReader reader) throw new FormatException(); BlockIndex = reader.ReadUInt32(); ValidatorIndex = reader.ReadByte(); - if (ValidatorIndex >= DBFTPlugin.System.Settings.ValidatorsCount) - throw new FormatException(); ViewNumber = reader.ReadByte(); } @@ -44,6 +42,11 @@ public static ConsensusMessage DeserializeFrom(byte[] data) return (ConsensusMessage)data.AsSerializable(t); } + public virtual bool Verify(ProtocolSettings protocolSettings) + { + return ValidatorIndex < protocolSettings.ValidatorsCount; + } + public virtual void Serialize(BinaryWriter writer) { writer.Write((byte)Type); diff --git a/src/DBFTPlugin/ConsensusService.cs b/src/DBFTPlugin/ConsensusService.cs index 6f67329c9..ebf825881 100644 --- a/src/DBFTPlugin/ConsensusService.cs +++ b/src/DBFTPlugin/ConsensusService.cs @@ -4,7 +4,6 @@ using Neo.Ledger; using Neo.Network.P2P; using Neo.Network.P2P.Payloads; -using Neo.Persistence; using Neo.SmartContract; using Neo.SmartContract.Native; using Neo.Wallets; @@ -45,17 +44,21 @@ private class Timer { public uint Height; public byte ViewNumber; } /// This variable is only true during OnRecoveryMessageReceived /// private bool isRecovering = false; + private readonly Settings dbftSettings; + private readonly NeoSystem neoSystem; - public ConsensusService(IActorRef localNode, IActorRef taskManager, IActorRef blockchain, IStore store, Wallet wallet) - : this(localNode, taskManager, blockchain, new ConsensusContext(wallet, store)) + public ConsensusService(NeoSystem neoSystem, Settings settings, Wallet wallet) + : this(neoSystem, settings, new ConsensusContext(neoSystem, settings, wallet)) { } - internal ConsensusService(IActorRef localNode, IActorRef taskManager, IActorRef blockchain, ConsensusContext context) + internal ConsensusService(NeoSystem neoSystem, Settings settings, ConsensusContext context) { - this.localNode = localNode; - this.taskManager = taskManager; - this.blockchain = blockchain; + this.neoSystem = neoSystem; + localNode = neoSystem.LocalNode; + taskManager = neoSystem.TaskManager; + blockchain = neoSystem.Blockchain; + dbftSettings = settings; this.context = context; Context.System.EventStream.Subscribe(Self, typeof(Blockchain.PersistCompleted)); Context.System.EventStream.Subscribe(Self, typeof(Blockchain.RelayResult)); @@ -65,7 +68,7 @@ private bool AddTransaction(Transaction tx, bool verify) { if (verify) { - VerifyResult result = tx.Verify(DBFTPlugin.System.Settings, context.Snapshot, context.VerificationContext); + VerifyResult result = tx.Verify(neoSystem.Settings, context.Snapshot, context.VerificationContext); if (result != VerifyResult.Succeed) { Log($"Rejected tx: {tx.Hash}, {result}{Environment.NewLine}{tx.ToArray().ToHexString()}", LogLevel.Warning); @@ -87,14 +90,14 @@ private bool CheckPrepareResponse() if (context.IsPrimary || context.WatchOnly) return true; // Check maximum block size via Native Contract policy - if (context.GetExpectedBlockSize() > Settings.Default.MaxBlockSize) + if (context.GetExpectedBlockSize() > dbftSettings.MaxBlockSize) { Log($"Rejected block: {context.Block.Index} The size exceed the policy", LogLevel.Warning); RequestChangeView(ChangeViewReason.BlockRejectedByPolicy); return false; } // Check maximum block system fee via Native Contract policy - if (context.GetExpectedBlockSystemFee() > Settings.Default.MaxBlockSystemFee) + if (context.GetExpectedBlockSystemFee() > dbftSettings.MaxBlockSystemFee) { Log($"Rejected block: {context.Block.Index} The system fee exceed the policy", LogLevel.Warning); RequestChangeView(ChangeViewReason.BlockRejectedByPolicy); @@ -164,7 +167,7 @@ private void CheckPreparations() context.Save(); localNode.Tell(new LocalNode.SendDirectly { Inventory = payload }); // Set timer, so we will resend the commit in case of a networking issue - ChangeTimer(TimeSpan.FromMilliseconds(DBFTPlugin.System.Settings.MillisecondsPerBlock)); + ChangeTimer(TimeSpan.FromMilliseconds(neoSystem.Settings.MillisecondsPerBlock)); CheckCommits(); } } @@ -180,11 +183,11 @@ private void InitializeConsensus(byte viewNumber) { if (isRecovering) { - ChangeTimer(TimeSpan.FromMilliseconds(DBFTPlugin.System.Settings.MillisecondsPerBlock << (viewNumber + 1))); + ChangeTimer(TimeSpan.FromMilliseconds(neoSystem.Settings.MillisecondsPerBlock << (viewNumber + 1))); } else { - TimeSpan span = DBFTPlugin.System.Settings.TimePerBlock; + TimeSpan span = neoSystem.Settings.TimePerBlock; if (block_received_index + 1 == context.Block.Index) { var diff = TimeProvider.Current.UtcNow - block_received_time; @@ -198,7 +201,7 @@ private void InitializeConsensus(byte viewNumber) } else { - ChangeTimer(TimeSpan.FromMilliseconds(DBFTPlugin.System.Settings.MillisecondsPerBlock << (viewNumber + 1))); + ChangeTimer(TimeSpan.FromMilliseconds(neoSystem.Settings.MillisecondsPerBlock << (viewNumber + 1))); } } @@ -241,7 +244,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(DBFTPlugin.System.Settings.Magic); + byte[] hashData = context.EnsureHeader()?.GetSignData(neoSystem.Settings.Magic); if (hashData == null) { existingCommitPayload = payload; @@ -263,7 +266,7 @@ private void OnCommitReceived(ExtensiblePayload payload, Commit commit) // this function increases existing timer (never decreases) with a value proportional to `maxDelayInBlockTimes`*`Blockchain.MillisecondsPerBlock` private void ExtendTimerByFactor(int maxDelayInBlockTimes) { - TimeSpan nextDelay = expected_delay - (TimeProvider.Current.UtcNow - clock_started) + TimeSpan.FromMilliseconds(maxDelayInBlockTimes * DBFTPlugin.System.Settings.MillisecondsPerBlock / (double)context.M); + TimeSpan nextDelay = expected_delay - (TimeProvider.Current.UtcNow - clock_started) + TimeSpan.FromMilliseconds(maxDelayInBlockTimes * neoSystem.Settings.MillisecondsPerBlock / (double)context.M); if (!context.WatchOnly && !context.ViewChanging && !context.CommitSent && (nextDelay > TimeSpan.Zero)) ChangeTimer(nextDelay); } @@ -284,6 +287,7 @@ private void OnConsensusPayload(ExtensiblePayload payload) { return; } + if (!message.Verify(neoSystem.Settings)) return; if (message.BlockIndex != context.Block.Index) { if (context.Block.Index < message.BlockIndex) @@ -412,9 +416,9 @@ private void OnPrepareRequestReceived(ExtensiblePayload payload, PrepareRequest if (context.RequestSentOrReceived || context.NotAcceptingPayloadsDueToViewChanging) return; if (message.ValidatorIndex != context.Block.PrimaryIndex || message.ViewNumber != context.ViewNumber) return; if (message.Version != context.Block.Version || message.PrevHash != context.Block.PrevHash) return; - if (message.TransactionHashes.Length > DBFTPlugin.System.Settings.MaxTransactionsPerBlock) return; + if (message.TransactionHashes.Length > neoSystem.Settings.MaxTransactionsPerBlock) return; Log($"{nameof(OnPrepareRequestReceived)}: height={message.BlockIndex} view={message.ViewNumber} index={message.ValidatorIndex} tx={message.TransactionHashes.Length}"); - if (message.Timestamp <= context.PrevHeader.Timestamp || message.Timestamp > TimeProvider.Current.UtcNow.AddMilliseconds(8 * DBFTPlugin.System.Settings.MillisecondsPerBlock).ToTimestampMS()) + if (message.Timestamp <= context.PrevHeader.Timestamp || message.Timestamp > TimeProvider.Current.UtcNow.AddMilliseconds(8 * neoSystem.Settings.MillisecondsPerBlock).ToTimestampMS()) { Log($"Timestamp incorrect: {message.Timestamp}", LogLevel.Warning); return; @@ -438,7 +442,7 @@ private void OnPrepareRequestReceived(ExtensiblePayload payload, PrepareRequest if (!context.GetMessage(context.PreparationPayloads[i]).PreparationHash.Equals(payload.Hash)) context.PreparationPayloads[i] = null; context.PreparationPayloads[message.ValidatorIndex] = payload; - byte[] hashData = context.EnsureHeader().GetSignData(DBFTPlugin.System.Settings.Magic); + byte[] hashData = context.EnsureHeader().GetSignData(neoSystem.Settings.Magic); for (int i = 0; i < context.CommitPayloads.Length; i++) if (context.GetMessage(context.CommitPayloads[i])?.ViewNumber == context.ViewNumber) if (!Crypto.VerifySignature(hashData, context.GetMessage(context.CommitPayloads[i]).Signature, context.Validators[i])) @@ -451,7 +455,7 @@ private void OnPrepareRequestReceived(ExtensiblePayload payload, PrepareRequest return; } - Dictionary mempoolVerified = DBFTPlugin.System.MemPool.GetVerifiedTransactions().ToDictionary(p => p.Hash); + Dictionary mempoolVerified = neoSystem.MemPool.GetVerifiedTransactions().ToDictionary(p => p.Hash); List unverified = new List(); foreach (UInt256 hash in context.TransactionHashes) { @@ -462,7 +466,7 @@ private void OnPrepareRequestReceived(ExtensiblePayload payload, PrepareRequest } else { - if (DBFTPlugin.System.MemPool.TryGetValue(hash, out tx)) + if (neoSystem.MemPool.TryGetValue(hash, out tx)) unverified.Add(tx); } } @@ -536,7 +540,7 @@ private void OnStart() { Log("OnStart"); started = true; - if (!Settings.Default.IgnoreRecoveryLogs && context.Load()) + if (!dbftSettings.IgnoreRecoveryLogs && context.Load()) { if (context.Transactions != null) { @@ -572,7 +576,7 @@ private void OnTimer(Timer timer) // Re-send commit periodically by sending recover message in case of a network issue. Log($"Sending {nameof(RecoveryMessage)} to resend {nameof(Commit)}"); localNode.Tell(new LocalNode.SendDirectly { Inventory = context.MakeRecoveryMessage() }); - ChangeTimer(TimeSpan.FromMilliseconds(DBFTPlugin.System.Settings.MillisecondsPerBlock << 1)); + ChangeTimer(TimeSpan.FromMilliseconds(neoSystem.Settings.MillisecondsPerBlock << 1)); } else { @@ -606,9 +610,9 @@ protected override void PostStop() base.PostStop(); } - public static Props Props(IActorRef localNode, IActorRef taskManager, IActorRef blockchain, IStore store, Wallet wallet) + public static Props Props(NeoSystem neoSystem, Settings dbftSettings, Wallet wallet) { - return Akka.Actor.Props.Create(() => new ConsensusService(localNode, taskManager, blockchain, store, wallet)); + return Akka.Actor.Props.Create(() => new ConsensusService(neoSystem, dbftSettings, wallet)); } private void RequestChangeView(ChangeViewReason reason) @@ -619,7 +623,7 @@ private void RequestChangeView(ChangeViewReason reason) // The latter may happen by nodes in higher views with, at least, `M` proofs byte expectedView = context.ViewNumber; expectedView++; - ChangeTimer(TimeSpan.FromMilliseconds(DBFTPlugin.System.Settings.MillisecondsPerBlock << (expectedView + 1))); + ChangeTimer(TimeSpan.FromMilliseconds(neoSystem.Settings.MillisecondsPerBlock << (expectedView + 1))); if ((context.CountCommitted + context.CountFailed) > context.F) { RequestRecovery(); @@ -653,7 +657,7 @@ private void SendPrepareRequest() foreach (InvPayload payload in InvPayload.CreateGroup(InventoryType.TX, context.TransactionHashes)) localNode.Tell(Message.Create(MessageCommand.Inv, payload)); } - ChangeTimer(TimeSpan.FromMilliseconds((DBFTPlugin.System.Settings.MillisecondsPerBlock << (context.ViewNumber + 1)) - (context.ViewNumber == 0 ? DBFTPlugin.System.Settings.MillisecondsPerBlock : 0))); + ChangeTimer(TimeSpan.FromMilliseconds((neoSystem.Settings.MillisecondsPerBlock << (context.ViewNumber + 1)) - (context.ViewNumber == 0 ? neoSystem.Settings.MillisecondsPerBlock : 0))); } } } diff --git a/src/DBFTPlugin/DBFTPlugin.cs b/src/DBFTPlugin/DBFTPlugin.cs index 9efd837b6..cc6942320 100644 --- a/src/DBFTPlugin/DBFTPlugin.cs +++ b/src/DBFTPlugin/DBFTPlugin.cs @@ -11,20 +11,21 @@ public class DBFTPlugin : Plugin, IP2PPlugin private IWalletProvider walletProvider; private IActorRef consensus; private bool started = false; - internal static NeoSystem System; + private NeoSystem neoSystem; + private Settings settings; public override string Description => "Consensus plugin with dBFT algorithm."; protected override void Configure() { - Settings.Load(GetConfiguration()); + settings = new Settings(GetConfiguration()); } protected override void OnSystemLoaded(NeoSystem system) { - if (system.Settings.Magic != Settings.Default.Network) return; - System = system; - System.ServiceAdded += NeoSystem_ServiceAdded; + if (system.Settings.Magic != settings.Network) return; + neoSystem = system; + neoSystem.ServiceAdded += NeoSystem_ServiceAdded; } private void NeoSystem_ServiceAdded(object sender, object service) @@ -32,8 +33,8 @@ private void NeoSystem_ServiceAdded(object sender, object service) if (service is IWalletProvider) { walletProvider = service as IWalletProvider; - System.ServiceAdded -= NeoSystem_ServiceAdded; - if (Settings.Default.AutoStart) + neoSystem.ServiceAdded -= NeoSystem_ServiceAdded; + if (settings.AutoStart) { walletProvider.WalletChanged += WalletProvider_WalletChanged; } @@ -52,11 +53,12 @@ private void OnStart() Start(walletProvider.GetWallet()); } - public void Start(Wallet wallet) + public void Start(Wallet wallet, Settings settings = null) { if (started) return; started = true; - consensus = System.ActorSystem.ActorOf(ConsensusService.Props(System.LocalNode, System.TaskManager, System.Blockchain, System.LoadStore(Settings.Default.RecoveryLogs), wallet)); + if (settings != null) this.settings = settings; + consensus = neoSystem.ActorSystem.ActorOf(ConsensusService.Props(neoSystem, this.settings, wallet)); consensus.Tell(new ConsensusService.Start()); } diff --git a/src/DBFTPlugin/PrepareRequest.cs b/src/DBFTPlugin/PrepareRequest.cs index 80d28caef..14eb98904 100644 --- a/src/DBFTPlugin/PrepareRequest.cs +++ b/src/DBFTPlugin/PrepareRequest.cs @@ -18,10 +18,7 @@ public class PrepareRequest : ConsensusMessage + sizeof(ulong) //Timestamp + TransactionHashes.GetVarSize(); //TransactionHashes - public PrepareRequest() - : base(ConsensusMessageType.PrepareRequest) - { - } + public PrepareRequest() : base(ConsensusMessageType.PrepareRequest) { } public override void Deserialize(BinaryReader reader) { @@ -34,6 +31,12 @@ public override void Deserialize(BinaryReader reader) throw new FormatException(); } + public override bool Verify(ProtocolSettings protocolSettings) + { + if (!base.Verify(protocolSettings)) return false; + return TransactionHashes.Length <= protocolSettings.MaxTransactionsPerBlock; + } + public override void Serialize(BinaryWriter writer) { base.Serialize(writer); diff --git a/src/DBFTPlugin/PrepareResponse.cs b/src/DBFTPlugin/PrepareResponse.cs index 7c2956ccc..f52f67298 100644 --- a/src/DBFTPlugin/PrepareResponse.cs +++ b/src/DBFTPlugin/PrepareResponse.cs @@ -9,10 +9,7 @@ public class PrepareResponse : ConsensusMessage public override int Size => base.Size + PreparationHash.Size; - public PrepareResponse() - : base(ConsensusMessageType.PrepareResponse) - { - } + public PrepareResponse() : base(ConsensusMessageType.PrepareResponse) { } public override void Deserialize(BinaryReader reader) { diff --git a/src/DBFTPlugin/RecoveryMessage.ChangeViewPayloadCompact.cs b/src/DBFTPlugin/RecoveryMessage.ChangeViewPayloadCompact.cs index ee81423f4..cd7114ed6 100644 --- a/src/DBFTPlugin/RecoveryMessage.ChangeViewPayloadCompact.cs +++ b/src/DBFTPlugin/RecoveryMessage.ChangeViewPayloadCompact.cs @@ -1,5 +1,4 @@ using Neo.IO; -using System; using System.IO; namespace Neo.Consensus @@ -22,8 +21,6 @@ public class ChangeViewPayloadCompact : ISerializable void ISerializable.Deserialize(BinaryReader reader) { ValidatorIndex = reader.ReadByte(); - if (ValidatorIndex >= DBFTPlugin.System.Settings.ValidatorsCount) - throw new FormatException(); OriginalViewNumber = reader.ReadByte(); Timestamp = reader.ReadUInt64(); InvocationScript = reader.ReadVarBytes(1024); diff --git a/src/DBFTPlugin/RecoveryMessage.CommitPayloadCompact.cs b/src/DBFTPlugin/RecoveryMessage.CommitPayloadCompact.cs index 115a00caa..f52c7932a 100644 --- a/src/DBFTPlugin/RecoveryMessage.CommitPayloadCompact.cs +++ b/src/DBFTPlugin/RecoveryMessage.CommitPayloadCompact.cs @@ -23,8 +23,6 @@ void ISerializable.Deserialize(BinaryReader reader) { ViewNumber = reader.ReadByte(); ValidatorIndex = reader.ReadByte(); - if (ValidatorIndex >= DBFTPlugin.System.Settings.ValidatorsCount) - throw new FormatException(); Signature = reader.ReadFixedBytes(64); InvocationScript = reader.ReadVarBytes(1024); } diff --git a/src/DBFTPlugin/RecoveryMessage.PreparationPayloadCompact.cs b/src/DBFTPlugin/RecoveryMessage.PreparationPayloadCompact.cs index b605e2811..65aecdb1f 100644 --- a/src/DBFTPlugin/RecoveryMessage.PreparationPayloadCompact.cs +++ b/src/DBFTPlugin/RecoveryMessage.PreparationPayloadCompact.cs @@ -1,5 +1,4 @@ using Neo.IO; -using System; using System.IO; namespace Neo.Consensus @@ -18,8 +17,6 @@ public class PreparationPayloadCompact : ISerializable void ISerializable.Deserialize(BinaryReader reader) { ValidatorIndex = reader.ReadByte(); - if (ValidatorIndex >= DBFTPlugin.System.Settings.ValidatorsCount) - throw new FormatException(); InvocationScript = reader.ReadVarBytes(1024); } diff --git a/src/DBFTPlugin/RecoveryMessage.cs b/src/DBFTPlugin/RecoveryMessage.cs index 6e0daff50..63b0f95ee 100644 --- a/src/DBFTPlugin/RecoveryMessage.cs +++ b/src/DBFTPlugin/RecoveryMessage.cs @@ -9,13 +9,13 @@ namespace Neo.Consensus { public partial class RecoveryMessage : ConsensusMessage { - public Dictionary ChangeViewMessages; + public Dictionary ChangeViewMessages; public PrepareRequest PrepareRequestMessage; /// The PreparationHash in case the PrepareRequest hasn't been received yet. /// This can be null if the PrepareRequest information is present, since it can be derived in that case. public UInt256 PreparationHash; - public Dictionary PreparationMessages; - public Dictionary CommitMessages; + public Dictionary PreparationMessages; + public Dictionary CommitMessages; public override int Size => base.Size + /* ChangeViewMessages */ ChangeViewMessages?.Values.GetVarSize() ?? 0 @@ -24,16 +24,16 @@ public partial class RecoveryMessage : ConsensusMessage + /* PreparationMessages */ PreparationMessages?.Values.GetVarSize() ?? 0 + /* CommitMessages */ CommitMessages?.Values.GetVarSize() ?? 0; - public RecoveryMessage() : base(ConsensusMessageType.RecoveryMessage) - { - } + public RecoveryMessage() : base(ConsensusMessageType.RecoveryMessage) { } public override void Deserialize(BinaryReader reader) { base.Deserialize(reader); - ChangeViewMessages = reader.ReadSerializableArray(DBFTPlugin.System.Settings.ValidatorsCount).ToDictionary(p => (int)p.ValidatorIndex); + ChangeViewMessages = reader.ReadSerializableArray(byte.MaxValue).ToDictionary(p => (int)p.ValidatorIndex); if (reader.ReadBoolean()) + { PrepareRequestMessage = reader.ReadSerializable(); + } else { int preparationHashSize = UInt256.Zero.Size; @@ -41,8 +41,17 @@ public override void Deserialize(BinaryReader reader) PreparationHash = new UInt256(reader.ReadFixedBytes(preparationHashSize)); } - PreparationMessages = reader.ReadSerializableArray(DBFTPlugin.System.Settings.ValidatorsCount).ToDictionary(p => (int)p.ValidatorIndex); - CommitMessages = reader.ReadSerializableArray(DBFTPlugin.System.Settings.ValidatorsCount).ToDictionary(p => (int)p.ValidatorIndex); + PreparationMessages = reader.ReadSerializableArray(byte.MaxValue).ToDictionary(p => p.ValidatorIndex); + CommitMessages = reader.ReadSerializableArray(byte.MaxValue).ToDictionary(p => p.ValidatorIndex); + } + + public override bool Verify(ProtocolSettings protocolSettings) + { + if (!base.Verify(protocolSettings)) return false; + return (PrepareRequestMessage is null || PrepareRequestMessage.Verify(protocolSettings)) + && ChangeViewMessages.Values.All(p => p.ValidatorIndex < protocolSettings.ValidatorsCount) + && PreparationMessages.Values.All(p => p.ValidatorIndex < protocolSettings.ValidatorsCount) + && CommitMessages.Values.All(p => p.ValidatorIndex < protocolSettings.ValidatorsCount); } internal ExtensiblePayload[] GetChangeViewPayloads(ConsensusContext context) diff --git a/src/DBFTPlugin/Settings.cs b/src/DBFTPlugin/Settings.cs index 7d252ec0a..29064d96f 100644 --- a/src/DBFTPlugin/Settings.cs +++ b/src/DBFTPlugin/Settings.cs @@ -2,7 +2,7 @@ namespace Neo.Consensus { - class Settings + public class Settings { public string RecoveryLogs { get; } public bool IgnoreRecoveryLogs { get; } @@ -11,9 +11,7 @@ class Settings public uint MaxBlockSize { get; } public long MaxBlockSystemFee { get; } - public static Settings Default { get; private set; } - - private Settings(IConfigurationSection section) + public Settings(IConfigurationSection section) { RecoveryLogs = section.GetValue("RecoveryLogs", "ConsensusState"); IgnoreRecoveryLogs = section.GetValue("IgnoreRecoveryLogs", false); @@ -22,10 +20,5 @@ private Settings(IConfigurationSection section) MaxBlockSize = section.GetValue("MaxBlockSize", 262144u); MaxBlockSystemFee = section.GetValue("MaxBlockSystemFee", 900000000000L); } - - public static void Load(IConfigurationSection section) - { - Default = new Settings(section); - } } } From 89dcaa059bd1bc87985dd657519ea1ed4932f099 Mon Sep 17 00:00:00 2001 From: Shine Li Date: Mon, 15 Mar 2021 14:41:26 +0800 Subject: [PATCH 09/30] fix (#558) --- src/DBFTPlugin/RecoveryMessage.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DBFTPlugin/RecoveryMessage.cs b/src/DBFTPlugin/RecoveryMessage.cs index 63b0f95ee..046fae5e3 100644 --- a/src/DBFTPlugin/RecoveryMessage.cs +++ b/src/DBFTPlugin/RecoveryMessage.cs @@ -29,7 +29,7 @@ public RecoveryMessage() : base(ConsensusMessageType.RecoveryMessage) { } public override void Deserialize(BinaryReader reader) { base.Deserialize(reader); - ChangeViewMessages = reader.ReadSerializableArray(byte.MaxValue).ToDictionary(p => (int)p.ValidatorIndex); + ChangeViewMessages = reader.ReadSerializableArray(byte.MaxValue).ToDictionary(p => p.ValidatorIndex); if (reader.ReadBoolean()) { PrepareRequestMessage = reader.ReadSerializable(); From a893ee040617807e8c90cebb9c9efeb1b8ef9365 Mon Sep 17 00:00:00 2001 From: HaoqiangZhang Date: Mon, 15 Mar 2021 17:05:37 +0800 Subject: [PATCH 10/30] Fix deploy contract in RpcClient (#559) * Fix deploy contract in RpcClient * fix ut --- src/RpcClient/ContractClient.cs | 2 +- tests/Neo.Network.RPC.Tests/UT_ContractClient.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/RpcClient/ContractClient.cs b/src/RpcClient/ContractClient.cs index acd1e50db..34d3869e8 100644 --- a/src/RpcClient/ContractClient.cs +++ b/src/RpcClient/ContractClient.cs @@ -50,7 +50,7 @@ public async Task CreateDeployContractTxAsync(byte[] nefFile, Contr byte[] script; using (ScriptBuilder sb = new ScriptBuilder()) { - sb.EmitDynamicCall(NativeContract.ContractManagement.Hash, "deploy", nefFile, manifest.ToString()); + sb.EmitDynamicCall(NativeContract.ContractManagement.Hash, "deploy", nefFile, manifest.ToJson().ToString()); script = sb.ToArray(); } UInt160 sender = Contract.CreateSignatureRedeemScript(key.PublicKey).ToScriptHash(); diff --git a/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs b/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs index 1c180f7da..4869138fb 100644 --- a/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs +++ b/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs @@ -55,7 +55,7 @@ public async Task TestDeployContract() }; using (ScriptBuilder sb = new ScriptBuilder()) { - sb.EmitDynamicCall(NativeContract.ContractManagement.Hash, "deploy", new byte[1], manifest.ToString()); + sb.EmitDynamicCall(NativeContract.ContractManagement.Hash, "deploy", new byte[1], manifest.ToJson().ToString()); script = sb.ToArray(); } From 09ab00edcfd859a3e8523598af2baba65ef0f351 Mon Sep 17 00:00:00 2001 From: HaoqiangZhang Date: Mon, 15 Mar 2021 18:05:13 +0800 Subject: [PATCH 11/30] update policy api (#561) * update policy api * Fix UT name Co-authored-by: Clay9910 <1174310571@qq.com> Co-authored-by: Owen Zhang <38493437+superboyiii@users.noreply.github.com> --- src/RpcClient/PolicyAPI.cs | 12 ++++++------ tests/Neo.Network.RPC.Tests/UT_PolicyAPI.cs | 20 ++++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/RpcClient/PolicyAPI.cs b/src/RpcClient/PolicyAPI.cs index 808906a39..16e076398 100644 --- a/src/RpcClient/PolicyAPI.cs +++ b/src/RpcClient/PolicyAPI.cs @@ -20,22 +20,22 @@ public class PolicyAPI : ContractClient public PolicyAPI(RpcClient rpcClient) : base(rpcClient) { } /// - /// Get Max Transactions Count Per Block + /// Get Fee Factor /// /// - public async Task GetMaxTransactionsPerBlockAsync() + public async Task GetExecFeeFactorAsync() { - var result = await TestInvokeAsync(scriptHash, "getMaxTransactionsPerBlock").ConfigureAwait(false); + var result = await TestInvokeAsync(scriptHash, "getExecFeeFactor").ConfigureAwait(false); return (uint)result.Stack.Single().GetInteger(); } /// - /// Get Max Block Size + /// Get Storage Price /// /// - public async Task GetMaxBlockSizeAsync() + public async Task GetStoragePriceAsync() { - var result = await TestInvokeAsync(scriptHash, "getMaxBlockSize").ConfigureAwait(false); + var result = await TestInvokeAsync(scriptHash, "getStoragePrice").ConfigureAwait(false); return (uint)result.Stack.Single().GetInteger(); } diff --git a/tests/Neo.Network.RPC.Tests/UT_PolicyAPI.cs b/tests/Neo.Network.RPC.Tests/UT_PolicyAPI.cs index 245636e93..610a25313 100644 --- a/tests/Neo.Network.RPC.Tests/UT_PolicyAPI.cs +++ b/tests/Neo.Network.RPC.Tests/UT_PolicyAPI.cs @@ -27,23 +27,23 @@ public void TestSetup() } [TestMethod] - public async Task TestGetMaxTransactionsPerBlock() + public async Task TestGetExecFeeFactor() { - byte[] testScript = NativeContract.Policy.Hash.MakeScript("getMaxTransactionsPerBlock"); - UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(512) }); + byte[] testScript = NativeContract.Policy.Hash.MakeScript("getExecFeeFactor"); + UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(30) }); - var result = await policyAPI.GetMaxTransactionsPerBlockAsync(); - Assert.AreEqual(512u, result); + var result = await policyAPI.GetExecFeeFactorAsync(); + Assert.AreEqual(30u, result); } [TestMethod] - public async Task TestGetMaxBlockSize() + public async Task TestGetStoragePrice() { - byte[] testScript = NativeContract.Policy.Hash.MakeScript("getMaxBlockSize"); - UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1024u * 256u) }); + byte[] testScript = NativeContract.Policy.Hash.MakeScript("getStoragePrice"); + UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(100000) }); - var result = await policyAPI.GetMaxBlockSizeAsync(); - Assert.AreEqual(1024u * 256u, result); + var result = await policyAPI.GetStoragePriceAsync(); + Assert.AreEqual(100000u, result); } [TestMethod] From 67cabb8da99ed2c436280d8aaeb606174574c814 Mon Sep 17 00:00:00 2001 From: ZhangTao Date: Mon, 15 Mar 2021 18:08:52 +0800 Subject: [PATCH 12/30] [Oracle] Optimize neofs return type (#554) * optimize neofs return * payload to utf8 string * Change to summary * Fix some results * Fix the result of GetHashAsync * fix header result * format json * update neofs-api-csharp Co-authored-by: Shargon Co-authored-by: Erik Zhang Co-authored-by: Owen Zhang <38493437+superboyiii@users.noreply.github.com> --- src/OracleService/OracleService.csproj | 2 +- .../Protocols/OracleNeoFSProtocol.cs | 49 ++++++++++++------- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/src/OracleService/OracleService.csproj b/src/OracleService/OracleService.csproj index aa6cc6d21..7604b119a 100644 --- a/src/OracleService/OracleService.csproj +++ b/src/OracleService/OracleService.csproj @@ -6,7 +6,7 @@ - + diff --git a/src/OracleService/Protocols/OracleNeoFSProtocol.cs b/src/OracleService/Protocols/OracleNeoFSProtocol.cs index 5db1324fb..b2470d65e 100644 --- a/src/OracleService/Protocols/OracleNeoFSProtocol.cs +++ b/src/OracleService/Protocols/OracleNeoFSProtocol.cs @@ -1,8 +1,9 @@ using Neo.Cryptography.ECC; -using Neo.FileSystem.API.Client; -using Neo.FileSystem.API.Client.ObjectParams; -using Neo.FileSystem.API.Cryptography; -using Neo.FileSystem.API.Refs; +using Neo.FileStorage.API.Client; +using Neo.FileStorage.API.Client.ObjectParams; +using Neo.FileStorage.API.Cryptography; +using Neo.FileStorage.API.Refs; +using Neo.IO.Json; using Neo.Network.P2P.Payloads; using Neo.Wallets; using System; @@ -11,8 +12,8 @@ using System.Threading; using System.Threading.Tasks; using System.Web; -using Object = Neo.FileSystem.API.Object.Object; -using Range = Neo.FileSystem.API.Object.Range; +using Object = Neo.FileStorage.API.Object.Object; +using Range = Neo.FileStorage.API.Object.Range; namespace Neo.Plugins { @@ -40,9 +41,9 @@ public void Dispose() Utility.Log(nameof(OracleNeoFSProtocol), LogLevel.Debug, $"Request: {uri.AbsoluteUri}"); try { - byte[] res = await GetAsync(uri, Settings.Default.NeoFS.EndPoint, cancellation); - Utility.Log(nameof(OracleNeoFSProtocol), LogLevel.Debug, $"NeoFS result: {res.ToHexString()}"); - return (OracleResponseCode.Success, Convert.ToBase64String(res)); + string res = await GetAsync(uri, Settings.Default.NeoFS.EndPoint, cancellation); + Utility.Log(nameof(OracleNeoFSProtocol), LogLevel.Debug, $"NeoFS result: {res}"); + return (OracleResponseCode.Success, res); } catch (Exception e) { @@ -51,7 +52,16 @@ public void Dispose() } } - private Task GetAsync(Uri uri, string host, CancellationToken cancellation) + + /// + /// GetAsync returns neofs object from the provided url. + /// If Command is not provided, full object is requested. + /// + /// URI scheme is "neofs:///". + /// Client host. + /// Cancellation token object. + /// Returns neofs object. + private Task GetAsync(Uri uri, string host, CancellationToken cancellation) { string[] ps = uri.AbsolutePath.Split("/"); if (ps.Length < 2) throw new FormatException("Invalid neofs url"); @@ -76,36 +86,37 @@ private Task GetAsync(Uri uri, string host, CancellationToken cancellati }; } - private static async Task GetPayloadAsync(Client client, Address addr, CancellationToken cancellation) + private static async Task GetPayloadAsync(Client client, Address addr, CancellationToken cancellation) { Object obj = await client.GetObject(cancellation, new GetObjectParams() { Address = addr }, new CallOptions { Ttl = 2 }); - return obj.Payload.ToByteArray(); + return obj.Payload.ToString(Utility.StrictUTF8); } - private static Task GetRangeAsync(Client client, Address addr, string[] ps, CancellationToken cancellation) + private static async Task GetRangeAsync(Client client, Address addr, string[] ps, CancellationToken cancellation) { if (ps.Length == 0) throw new FormatException("missing object range (expected 'Offset|Length')"); Range range = ParseRange(ps[0]); - return client.GetObjectPayloadRangeData(cancellation, new RangeDataParams() { Address = addr, Range = range }, new CallOptions { Ttl = 2 }); + var res = await client.GetObjectPayloadRangeData(cancellation, new RangeDataParams() { Address = addr, Range = range }, new CallOptions { Ttl = 2 }); + return Utility.StrictUTF8.GetString(res); } - private static async Task GetHeaderAsync(Client client, Address addr, CancellationToken cancellation) + private static async Task GetHeaderAsync(Client client, Address addr, CancellationToken cancellation) { var obj = await client.GetObjectHeader(cancellation, new ObjectHeaderParams() { Address = addr }, new CallOptions { Ttl = 2 }); - return Utility.StrictUTF8.GetBytes(obj.ToString()); + return obj.ToJson().ToString(); } - private static async Task GetHashAsync(Client client, Address addr, string[] ps, CancellationToken cancellation) + private static async Task GetHashAsync(Client client, Address addr, string[] ps, CancellationToken cancellation) { if (ps.Length == 0 || ps[0] == "") { Object obj = await client.GetObjectHeader(cancellation, new ObjectHeaderParams() { Address = addr }, new CallOptions { Ttl = 2 }); - return obj.PayloadChecksum.Sum.ToByteArray(); + return $"\"{new UInt256(obj.PayloadChecksum.Sum.ToByteArray())}\""; } Range range = ParseRange(ps[0]); List hashes = await client.GetObjectPayloadRangeHash(cancellation, new RangeChecksumParams() { Address = addr, Ranges = new List() { range }, Type = ChecksumType.Sha256, Salt = Array.Empty() }, new CallOptions { Ttl = 2 }); if (hashes.Count == 0) throw new Exception("empty response, object range is invalid (expected 'Offset|Length')"); - return hashes[0]; + return $"\"{new UInt256(hashes[0])}\""; } private static Range ParseRange(string s) From 06d6cbd63c4b87e3cc29f12550ff5a8fefc58d60 Mon Sep 17 00:00:00 2001 From: bettybao1209 Date: Mon, 15 Mar 2021 19:48:32 +0800 Subject: [PATCH 13/30] [RpcServer] fix decimal (#562) --- src/RpcServer/RpcServer.Wallet.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/RpcServer/RpcServer.Wallet.cs b/src/RpcServer/RpcServer.Wallet.cs index 7c75e628f..e02df46d4 100644 --- a/src/RpcServer/RpcServer.Wallet.cs +++ b/src/RpcServer/RpcServer.Wallet.cs @@ -207,7 +207,7 @@ protected virtual JObject SendFrom(JArray _params) UInt160 to = AddressToScriptHash(_params[2].AsString(), system.Settings.AddressVersion); using var snapshot = system.GetSnapshot(); AssetDescriptor descriptor = new AssetDescriptor(snapshot, system.Settings, assetId); - BigDecimal amount = BigDecimal.Parse(_params[3].AsString(), descriptor.Decimals); + BigDecimal amount = new BigDecimal(BigInteger.Parse(_params[3].AsString()), descriptor.Decimals); if (amount.Sign <= 0) throw new RpcException(-32602, "Invalid params"); Signer[] signers = _params.Count >= 5 ? ((JArray)_params[4]).Select(p => new Signer() { Account = AddressToScriptHash(p.AsString(), system.Settings.AddressVersion), Scopes = WitnessScope.CalledByEntry }).ToArray() : null; @@ -299,7 +299,7 @@ protected virtual JObject SendToAddress(JArray _params) UInt160 to = AddressToScriptHash(_params[1].AsString(), system.Settings.AddressVersion); using var snapshot = system.GetSnapshot(); AssetDescriptor descriptor = new AssetDescriptor(snapshot, system.Settings, assetId); - BigDecimal amount = BigDecimal.Parse(_params[2].AsString(), descriptor.Decimals); + BigDecimal amount = new BigDecimal(BigInteger.Parse(_params[2].AsString()), descriptor.Decimals); if (amount.Sign <= 0) throw new RpcException(-32602, "Invalid params"); Transaction tx = wallet.MakeTransaction(snapshot, new[] From 93fb62019bec6606c406e337706d5c5e235f948c Mon Sep 17 00:00:00 2001 From: Harry Pierson Date: Mon, 15 Mar 2021 20:07:26 -0700 Subject: [PATCH 14/30] move Settings paramter to dbft plugin ctor (#563) --- src/DBFTPlugin/DBFTPlugin.cs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/DBFTPlugin/DBFTPlugin.cs b/src/DBFTPlugin/DBFTPlugin.cs index cc6942320..6336959d5 100644 --- a/src/DBFTPlugin/DBFTPlugin.cs +++ b/src/DBFTPlugin/DBFTPlugin.cs @@ -14,11 +14,18 @@ public class DBFTPlugin : Plugin, IP2PPlugin private NeoSystem neoSystem; private Settings settings; + public DBFTPlugin() { } + + public DBFTPlugin(Settings settings) + { + this.settings = settings; + } + public override string Description => "Consensus plugin with dBFT algorithm."; protected override void Configure() { - settings = new Settings(GetConfiguration()); + if (settings == null) settings = new Settings(GetConfiguration()); } protected override void OnSystemLoaded(NeoSystem system) @@ -53,12 +60,11 @@ private void OnStart() Start(walletProvider.GetWallet()); } - public void Start(Wallet wallet, Settings settings = null) + public void Start(Wallet wallet) { if (started) return; started = true; - if (settings != null) this.settings = settings; - consensus = neoSystem.ActorSystem.ActorOf(ConsensusService.Props(neoSystem, this.settings, wallet)); + consensus = neoSystem.ActorSystem.ActorOf(ConsensusService.Props(neoSystem, settings, wallet)); consensus.Tell(new ConsensusService.Start()); } From 01c2e9561b4080071637964a959be0b79d594b9d Mon Sep 17 00:00:00 2001 From: Owen Zhang <38493437+superboyiii@users.noreply.github.com> Date: Wed, 17 Mar 2021 18:05:33 +0800 Subject: [PATCH 15/30] 3.0.0-CI01246 (#565) --- src/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index a4d2a41af..17ae6e0ee 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -15,7 +15,7 @@ - + From 1c24a3fdb3d615de63410d15257c3d9962a7a5d2 Mon Sep 17 00:00:00 2001 From: Shine Li Date: Wed, 17 Mar 2021 23:12:38 +0800 Subject: [PATCH 16/30] fix verify api (#564) * fix verify api * refac * default signer & parameter * refac * add Witness * format * update * update * update Co-authored-by: Owen Zhang <38493437+superboyiii@users.noreply.github.com> --- src/RpcServer/RpcServer.SmartContract.cs | 16 ++++++++++- src/RpcServer/RpcServer.Wallet.cs | 35 ++++++++++++++++-------- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/RpcServer/RpcServer.SmartContract.cs b/src/RpcServer/RpcServer.SmartContract.cs index f5a2c5481..b373175ec 100644 --- a/src/RpcServer/RpcServer.SmartContract.cs +++ b/src/RpcServer/RpcServer.SmartContract.cs @@ -97,7 +97,21 @@ private static Signers SignersFromJson(JArray _params, ProtocolSettings settings Scopes = (WitnessScope)Enum.Parse(typeof(WitnessScope), u["scopes"]?.AsString()), AllowedContracts = ((JArray)u["allowedcontracts"])?.Select(p => UInt160.Parse(p.AsString())).ToArray(), AllowedGroups = ((JArray)u["allowedgroups"])?.Select(p => ECPoint.Parse(p.AsString(), ECCurve.Secp256r1)).ToArray() - }).ToArray()); + }).ToArray()) + { + Witnesses = _params + .Select(u => new + { + Invocation = u["invocation"]?.AsString(), + Verification = u["verification"]?.AsString() + }) + .Where(x => x.Invocation != null || x.Verification != null) + .Select(x => new Witness() + { + InvocationScript = Convert.FromBase64String(x.Invocation ?? string.Empty), + VerificationScript = Convert.FromBase64String(x.Verification ?? string.Empty) + }).ToArray() + }; // Validate format diff --git a/src/RpcServer/RpcServer.Wallet.cs b/src/RpcServer/RpcServer.Wallet.cs index e02df46d4..48ef8abe2 100644 --- a/src/RpcServer/RpcServer.Wallet.cs +++ b/src/RpcServer/RpcServer.Wallet.cs @@ -333,7 +333,6 @@ protected virtual JObject SendToAddress(JArray _params) [RpcMethod] protected virtual JObject InvokeContractVerify(JArray _params) { - CheckWallet(); UInt160 script_hash = UInt160.Parse(_params[0].AsString()); ContractParameter[] args = _params.Count >= 2 ? ((JArray)_params[1]).Select(p => ContractParameter.FromJson(p)).ToArray() : new ContractParameter[0]; Signers signers = _params.Count >= 3 ? SignersFromJson((JArray)_params[2], system.Settings) : null; @@ -348,22 +347,36 @@ private JObject GetVerificationResult(UInt160 scriptHash, ContractParameter[] ar { throw new RpcException(-100, "Unknown contract"); } - var methodName = "verify"; + var md = contract.Manifest.Abi.GetMethod("verify", -1); + if (md is null) + throw new RpcException(-101, $"The smart contract {contract.Hash} haven't got verify method."); + if (md.ReturnType != ContractParameterType.Boolean) + throw new RpcException(-102, "The verify method doesn't return boolean value."); - Transaction tx = signers == null ? null : new Transaction + Transaction tx = new Transaction { - Signers = signers.GetSigners(), - Attributes = Array.Empty() + Signers = signers == null ? new Signer[] { new() { Account = scriptHash } } : signers.GetSigners(), + Attributes = Array.Empty(), + Witnesses = signers?.Witnesses, + Script = new[] { (byte)OpCode.RET } }; - ContractParametersContext context = new ContractParametersContext(snapshot, tx); - wallet.Sign(context); - tx.Witnesses = context.Completed ? context.GetWitnesses() : null; - using ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot.CreateSnapshot(), settings: system.Settings); - engine.LoadScript(new ScriptBuilder().EmitDynamicCall(scriptHash, methodName, args).ToArray(), rvcount: 1); + engine.LoadContract(contract, md, CallFlags.ReadOnly); + var invocationScript = new byte[] { }; + if (args.Length > 0) + { + using ScriptBuilder sb = new ScriptBuilder(); + for (int i = args.Length - 1; i >= 0; i--) + sb.EmitPush(args[i]); + + invocationScript = sb.ToArray(); + tx.Witnesses ??= new Witness[] { new() { InvocationScript = invocationScript } }; + engine.LoadScript(new Script(invocationScript), configureState: p => p.CallFlags = CallFlags.None); + } JObject json = new JObject(); - json["script"] = Convert.ToBase64String(contract.Script); + + json["script"] = Convert.ToBase64String(invocationScript); json["state"] = engine.Execute(); json["gasconsumed"] = engine.GasConsumed.ToString(); json["exception"] = GetExceptionMessage(engine.FaultException); From 5bd92ab880378895f422be2062fd53598cce41e2 Mon Sep 17 00:00:00 2001 From: Erik Zhang Date: Wed, 17 Mar 2021 23:20:15 +0800 Subject: [PATCH 17/30] RC1 (#566) --- src/Directory.Build.props | 4 ++-- src/RocksDBStore/RocksDBStore.csproj | 2 +- tests/Directory.Build.props | 6 +++--- tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj | 6 +++--- .../Neo.Plugins.OracleService.Tests.csproj | 4 ++-- .../Neo.Plugins.RpcServer.Tests.csproj | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 17ae6e0ee..f35038d31 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -3,7 +3,7 @@ 3.0.0 - preview5 + rc1 net5.0 Neo.Plugins The Neo Project @@ -15,7 +15,7 @@ - + diff --git a/src/RocksDBStore/RocksDBStore.csproj b/src/RocksDBStore/RocksDBStore.csproj index ca48152a9..93703615d 100644 --- a/src/RocksDBStore/RocksDBStore.csproj +++ b/src/RocksDBStore/RocksDBStore.csproj @@ -6,7 +6,7 @@ - + diff --git a/tests/Directory.Build.props b/tests/Directory.Build.props index 3a7fa1350..c92b2f425 100644 --- a/tests/Directory.Build.props +++ b/tests/Directory.Build.props @@ -7,9 +7,9 @@ - - - + + + diff --git a/tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj b/tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj index 3209d575a..000b6dcd8 100644 --- a/tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj +++ b/tests/Neo.Network.RPC.Tests/Neo.Network.RPC.Tests.csproj @@ -5,9 +5,9 @@ - - - + + + diff --git a/tests/Neo.Plugins.OracleService.Tests/Neo.Plugins.OracleService.Tests.csproj b/tests/Neo.Plugins.OracleService.Tests/Neo.Plugins.OracleService.Tests.csproj index 8c612c092..f4e296bea 100644 --- a/tests/Neo.Plugins.OracleService.Tests/Neo.Plugins.OracleService.Tests.csproj +++ b/tests/Neo.Plugins.OracleService.Tests/Neo.Plugins.OracleService.Tests.csproj @@ -6,8 +6,8 @@ - - + + diff --git a/tests/Neo.Plugins.RpcServer.Tests/Neo.Plugins.RpcServer.Tests.csproj b/tests/Neo.Plugins.RpcServer.Tests/Neo.Plugins.RpcServer.Tests.csproj index ef86a9969..e9a6a0ac5 100644 --- a/tests/Neo.Plugins.RpcServer.Tests/Neo.Plugins.RpcServer.Tests.csproj +++ b/tests/Neo.Plugins.RpcServer.Tests/Neo.Plugins.RpcServer.Tests.csproj @@ -10,7 +10,7 @@ - + From e2b973febd2859b805154b050ea11cce6f6c4b65 Mon Sep 17 00:00:00 2001 From: ZhangTao Date: Thu, 18 Mar 2021 11:41:47 +0800 Subject: [PATCH 18/30] update neofs-api (#567) --- src/OracleService/OracleService.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OracleService/OracleService.csproj b/src/OracleService/OracleService.csproj index 7604b119a..c08220fca 100644 --- a/src/OracleService/OracleService.csproj +++ b/src/OracleService/OracleService.csproj @@ -6,7 +6,7 @@ - + From b61ec2c0fd0fff3bd6a29ae8112bf74dcf7f4995 Mon Sep 17 00:00:00 2001 From: AnnaShaleva Date: Tue, 23 Mar 2021 04:59:08 +0300 Subject: [PATCH 19/30] StatesDumper: fix bug with missing states dumps (#568) * StatesDumper: fix OnPersistStorage It didn't save anything to cache because bs_cache was always empty. As a result, there were no storage dumps on disc. Fixed. * StatesDumper: fix OnCommitStorage We already have created path inside the HandlePaths method, no need to create it one more time. * fix-format Co-authored-by: superboyiii <573504781@qq.com> --- src/StatesDumper/StatesDumper.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/StatesDumper/StatesDumper.cs b/src/StatesDumper/StatesDumper.cs index 3df94faef..3b7621e48 100644 --- a/src/StatesDumper/StatesDumper.cs +++ b/src/StatesDumper/StatesDumper.cs @@ -54,7 +54,6 @@ void IPersistencePlugin.OnPersist(NeoSystem system, Block block, DataCache snaps private void OnPersistStorage(uint network, DataCache snapshot) { - if (!bs_cache.TryGetValue(network, out JArray cache)) return; uint blockIndex = NativeContract.Ledger.CurrentIndex(snapshot); if (blockIndex >= Settings.Default.HeightToBegin) { @@ -90,7 +89,12 @@ private void OnPersistStorage(uint network, DataCache snapshot) bs_item["block"] = blockIndex; bs_item["size"] = array.Count; bs_item["storage"] = array; + if (!bs_cache.TryGetValue(network, out JArray cache)) + { + cache = new JArray(); + } cache.Add(bs_item); + bs_cache[network] = cache; } } @@ -108,7 +112,6 @@ void OnCommitStorage(uint network, DataCache snapshot) if ((blockIndex % Settings.Default.BlockCacheSize == 0) || (Settings.Default.HeightToStartRealTimeSyncing != -1 && blockIndex >= Settings.Default.HeightToStartRealTimeSyncing)) { string path = HandlePaths(network, blockIndex); - Directory.CreateDirectory(path); path = $"{path}/dump-block-{blockIndex}.json"; File.WriteAllText(path, cache.ToString()); cache.Clear(); From 9dc37f89592a68691d6564d07403b9992afc0814 Mon Sep 17 00:00:00 2001 From: bettybao1209 Date: Wed, 24 Mar 2021 21:35:42 +0800 Subject: [PATCH 20/30] [RpcClient & OracleService] Fix ut and sync fs (#570) --- src/Directory.Build.props | 2 +- src/OracleService/OracleService.csproj | 4 ++-- src/OracleService/Protocols/OracleNeoFSProtocol.cs | 10 +++++----- tests/Neo.Network.RPC.Tests/UT_ContractClient.cs | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index f35038d31..cf3ab0ab8 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -15,7 +15,7 @@ - + diff --git a/src/OracleService/OracleService.csproj b/src/OracleService/OracleService.csproj index c08220fca..c65ad1468 100644 --- a/src/OracleService/OracleService.csproj +++ b/src/OracleService/OracleService.csproj @@ -6,7 +6,7 @@ - + @@ -19,5 +19,5 @@ PreserveNewest - + diff --git a/src/OracleService/Protocols/OracleNeoFSProtocol.cs b/src/OracleService/Protocols/OracleNeoFSProtocol.cs index b2470d65e..98fd0218c 100644 --- a/src/OracleService/Protocols/OracleNeoFSProtocol.cs +++ b/src/OracleService/Protocols/OracleNeoFSProtocol.cs @@ -88,7 +88,7 @@ private Task GetAsync(Uri uri, string host, CancellationToken cancellati private static async Task GetPayloadAsync(Client client, Address addr, CancellationToken cancellation) { - Object obj = await client.GetObject(cancellation, new GetObjectParams() { Address = addr }, new CallOptions { Ttl = 2 }); + Object obj = await client.GetObject(new GetObjectParams() { Address = addr }, new CallOptions { Ttl = 2 }, cancellation); return obj.Payload.ToString(Utility.StrictUTF8); } @@ -96,13 +96,13 @@ private static async Task GetRangeAsync(Client client, Address addr, str { if (ps.Length == 0) throw new FormatException("missing object range (expected 'Offset|Length')"); Range range = ParseRange(ps[0]); - var res = await client.GetObjectPayloadRangeData(cancellation, new RangeDataParams() { Address = addr, Range = range }, new CallOptions { Ttl = 2 }); + var res = await client.GetObjectPayloadRangeData(new RangeDataParams() { Address = addr, Range = range }, new CallOptions { Ttl = 2 }, cancellation); return Utility.StrictUTF8.GetString(res); } private static async Task GetHeaderAsync(Client client, Address addr, CancellationToken cancellation) { - var obj = await client.GetObjectHeader(cancellation, new ObjectHeaderParams() { Address = addr }, new CallOptions { Ttl = 2 }); + var obj = await client.GetObjectHeader(new ObjectHeaderParams() { Address = addr }, new CallOptions { Ttl = 2 }, cancellation); return obj.ToJson().ToString(); } @@ -110,11 +110,11 @@ private static async Task GetHashAsync(Client client, Address addr, stri { if (ps.Length == 0 || ps[0] == "") { - Object obj = await client.GetObjectHeader(cancellation, new ObjectHeaderParams() { Address = addr }, new CallOptions { Ttl = 2 }); + Object obj = await client.GetObjectHeader(new ObjectHeaderParams() { Address = addr }, new CallOptions { Ttl = 2 }, cancellation); return $"\"{new UInt256(obj.PayloadChecksum.Sum.ToByteArray())}\""; } Range range = ParseRange(ps[0]); - List hashes = await client.GetObjectPayloadRangeHash(cancellation, new RangeChecksumParams() { Address = addr, Ranges = new List() { range }, Type = ChecksumType.Sha256, Salt = Array.Empty() }, new CallOptions { Ttl = 2 }); + List hashes = await client.GetObjectPayloadRangeHash(new RangeChecksumParams() { Address = addr, Ranges = new List() { range }, Type = ChecksumType.Sha256, Salt = Array.Empty() }, new CallOptions { Ttl = 2 }, cancellation); if (hashes.Count == 0) throw new Exception("empty response, object range is invalid (expected 'Offset|Length')"); return $"\"{new UInt256(hashes[0])}\""; } diff --git a/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs b/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs index 4869138fb..b46289f8a 100644 --- a/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs +++ b/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs @@ -49,7 +49,7 @@ public async Task TestDeployContract() Methods = new ContractMethodDescriptor[0] }, Groups = new ContractGroup[0], - Trusts = WildcardContainer.Create(), + Trusts = WildcardContainer.Create(), SupportedStandards = new string[] { "NEP-10" }, Extra = null, }; From e77f07401d81724b088b65fd6c63b428c6625837 Mon Sep 17 00:00:00 2001 From: ZhangTao Date: Thu, 25 Mar 2021 06:01:18 +0800 Subject: [PATCH 21/30] fix null store when network not match (#571) Co-authored-by: Erik Zhang --- src/StateService/StatePlugin.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/StateService/StatePlugin.cs b/src/StateService/StatePlugin.cs index 28a849321..6e7631a3c 100644 --- a/src/StateService/StatePlugin.cs +++ b/src/StateService/StatePlugin.cs @@ -67,8 +67,8 @@ private void WalletProvider_WalletChanged(object sender, Wallet wallet) public override void Dispose() { base.Dispose(); - System.EnsureStoped(Store); - if (Verifier != null) System.EnsureStoped(Verifier); + if (Store is not null) System.EnsureStoped(Store); + if (Verifier is not null) System.EnsureStoped(Verifier); } void IPersistencePlugin.OnPersist(NeoSystem system, Block block, DataCache snapshot, IReadOnlyList applicationExecutedList) @@ -86,7 +86,7 @@ private void OnStartVerifyingState() public void Start(Wallet wallet) { - if (Verifier != null) + if (Verifier is not null) { Console.WriteLine("Already started!"); return; From 86d0e4b9588bb7a2b9c919b31783a6d9a02b2690 Mon Sep 17 00:00:00 2001 From: ZhangTao Date: Tue, 30 Mar 2021 21:49:58 +0800 Subject: [PATCH 22/30] [StateService] Add sender check (#575) --- .../Verification/VerificationContext.cs | 31 +++++++++++++------ .../Verification/VerificationService.cs | 2 +- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/StateService/Verification/VerificationContext.cs b/src/StateService/Verification/VerificationContext.cs index 398bf1a4b..248bb5f0a 100644 --- a/src/StateService/Verification/VerificationContext.cs +++ b/src/StateService/Verification/VerificationContext.cs @@ -33,6 +33,15 @@ class VerificationContext public int MyIndex => myIndex; public uint RootIndex => rootIndex; public ECPoint[] Verifiers => verifiers; + public int Sender + { + get + { + int p = ((int)rootIndex - Retries) % verifiers.Length; + return p >= 0 ? p : p + verifiers.Length; + } + } + public bool IsSender => myIndex == Sender; public ICancelable Timer; public StateRoot StateRoot { @@ -111,17 +120,21 @@ public bool CheckSignatures() { if (StateRoot is null) return false; if (signatures.Count < M) return false; - if (StateRoot.Witness != null) return true; - Contract contract = Contract.CreateMultiSigContract(M, verifiers); - ContractParametersContext sc = new ContractParametersContext(StatePlugin.System.StoreView, StateRoot); - for (int i = 0, j = 0; i < verifiers.Length && j < M; i++) + if (StateRoot.Witness is null) { - if (!signatures.TryGetValue(i, out byte[] sig)) continue; - sc.AddSignature(contract, verifiers[i], sig); - j++; + Contract contract = Contract.CreateMultiSigContract(M, verifiers); + ContractParametersContext sc = new(StatePlugin.System.StoreView, StateRoot); + for (int i = 0, j = 0; i < verifiers.Length && j < M; i++) + { + if (!signatures.TryGetValue(i, out byte[] sig)) continue; + sc.AddSignature(contract, verifiers[i], sig); + j++; + } + if (!sc.Completed) return false; + StateRoot.Witness = sc.GetWitnesses()[0]; } - StateRoot.Witness = sc.GetWitnesses()[0]; - rootPayload = CreatePayload(MessageType.StateRoot, StateRoot, MaxValidUntilBlockIncrement); + if (IsSender) + rootPayload = CreatePayload(MessageType.StateRoot, StateRoot, MaxValidUntilBlockIncrement); return true; } diff --git a/src/StateService/Verification/VerificationService.cs b/src/StateService/Verification/VerificationService.cs index f3f7afd6b..93a5780e1 100644 --- a/src/StateService/Verification/VerificationService.cs +++ b/src/StateService/Verification/VerificationService.cs @@ -45,7 +45,7 @@ private void OnStateRootVote(Vote vote) private void CheckVotes(VerificationContext context) { - if (context.CheckSignatures()) + if (context.IsSender && context.CheckSignatures()) { if (context.StateRootMessage is null) return; Utility.Log(nameof(VerificationService), LogLevel.Info, $"relay state root, height={context.StateRoot.Index}, root={context.StateRoot.RootHash}"); From 571fb1c57ed55755f3988b6d10ea5e99db1ab35f Mon Sep 17 00:00:00 2001 From: Shargon Date: Wed, 31 Mar 2021 10:16:55 +0200 Subject: [PATCH 23/30] Fix (#574) Co-authored-by: Owen Zhang <38493437+superboyiii@users.noreply.github.com> --- src/RpcServer/RpcServer.Wallet.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/RpcServer/RpcServer.Wallet.cs b/src/RpcServer/RpcServer.Wallet.cs index 48ef8abe2..4ed5b059c 100644 --- a/src/RpcServer/RpcServer.Wallet.cs +++ b/src/RpcServer/RpcServer.Wallet.cs @@ -178,14 +178,14 @@ private void ProcessInvokeWithWallet(JObject result, Signers signers = null) Transaction tx; try { - tx = wallet.MakeTransaction(system.StoreView, Convert.FromBase64String(result["script"].AsString()), sender, witnessSigners); + tx = wallet.MakeTransaction(system.StoreView, Convert.FromBase64String(result["script"].AsString()), sender, witnessSigners, maxGas: settings.MaxGasInvoke); } catch (Exception e) { result["exception"] = GetExceptionMessage(e); return; } - ContractParametersContext context = new ContractParametersContext(system.StoreView, tx); + ContractParametersContext context = new(system.StoreView, tx); wallet.Sign(context); if (context.Completed) { From 736f5bc2a6e5ec724604c0aad95e7c1da0407e19 Mon Sep 17 00:00:00 2001 From: Owen Zhang <38493437+superboyiii@users.noreply.github.com> Date: Wed, 31 Mar 2021 16:20:53 +0800 Subject: [PATCH 24/30] Sync to Neov3.0.0-CI01257 (#576) * Sync to Neov3.0.0-CI01257 * fix --- src/ApplicationLogs/LogReader.cs | 4 ++-- src/DBFTPlugin/ConsensusContext.cs | 6 +++--- src/DBFTPlugin/ConsensusService.cs | 4 ++-- src/DBFTPlugin/DBFTPlugin.cs | 2 +- src/Directory.Build.props | 2 +- src/OracleService/OracleService.cs | 16 ++++++++-------- src/RpcClient/TransactionManager.cs | 4 ++-- src/RpcNep17Tracker/RpcNep17Tracker.cs | 8 ++++---- src/RpcServer/RpcServer.Node.cs | 2 +- src/RpcServer/RpcServer.Wallet.cs | 10 +++++----- src/RpcServer/RpcServerPlugin.cs | 2 +- src/StateService/StatePlugin.cs | 14 +++++++------- .../Verification/VerificationContext.cs | 8 ++++---- src/StatesDumper/StatesDumper.cs | 6 +++--- .../UT_TransactionManager.cs | 2 +- 15 files changed, 45 insertions(+), 45 deletions(-) diff --git a/src/ApplicationLogs/LogReader.cs b/src/ApplicationLogs/LogReader.cs index 8e286c443..65657d35f 100644 --- a/src/ApplicationLogs/LogReader.cs +++ b/src/ApplicationLogs/LogReader.cs @@ -29,7 +29,7 @@ protected override void Configure() protected override void OnSystemLoaded(NeoSystem system) { - if (system.Settings.Magic != Settings.Default.Network) return; + if (system.Settings.Network != Settings.Default.Network) return; RpcServerPlugin.RegisterMethods(this, Settings.Default.Network); } @@ -145,7 +145,7 @@ public static JObject BlockLogToJson(Block block, IReadOnlyList applicationExecutedList) { - if (system.Settings.Magic != Settings.Default.Network) return; + if (system.Settings.Network != Settings.Default.Network) return; WriteBatch writeBatch = new WriteBatch(); diff --git a/src/DBFTPlugin/ConsensusContext.cs b/src/DBFTPlugin/ConsensusContext.cs index 5d2c60c57..a9eb255e5 100644 --- a/src/DBFTPlugin/ConsensusContext.cs +++ b/src/DBFTPlugin/ConsensusContext.cs @@ -108,7 +108,7 @@ public Block CreateBlock() { EnsureHeader(); Contract contract = Contract.CreateMultiSigContract(M, Validators); - ContractParametersContext sc = new ContractParametersContext(neoSystem.StoreView, Block.Header); + ContractParametersContext sc = new ContractParametersContext(neoSystem.StoreView, Block.Header, dbftSettings.Network); for (int i = 0, j = 0; i < Validators.Length && j < M; i++) { if (GetMessage(CommitPayloads[i])?.ViewNumber != ViewNumber) continue; @@ -269,7 +269,7 @@ public ExtensiblePayload MakeCommit() { return CommitPayloads[MyIndex] ?? (CommitPayloads[MyIndex] = MakeSignedPayload(new Commit { - Signature = EnsureHeader().Sign(keyPair, neoSystem.Settings.Magic) + Signature = EnsureHeader().Sign(keyPair, neoSystem.Settings.Network) })); } @@ -288,7 +288,7 @@ private void SignPayload(ExtensiblePayload payload) ContractParametersContext sc; try { - sc = new ContractParametersContext(neoSystem.StoreView, payload); + sc = new ContractParametersContext(neoSystem.StoreView, payload, dbftSettings.Network); wallet.Sign(sc); } catch (InvalidOperationException) diff --git a/src/DBFTPlugin/ConsensusService.cs b/src/DBFTPlugin/ConsensusService.cs index ebf825881..125141e35 100644 --- a/src/DBFTPlugin/ConsensusService.cs +++ b/src/DBFTPlugin/ConsensusService.cs @@ -244,7 +244,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.Magic); + byte[] hashData = context.EnsureHeader()?.GetSignData(neoSystem.Settings.Network); if (hashData == null) { existingCommitPayload = payload; @@ -442,7 +442,7 @@ private void OnPrepareRequestReceived(ExtensiblePayload payload, PrepareRequest if (!context.GetMessage(context.PreparationPayloads[i]).PreparationHash.Equals(payload.Hash)) context.PreparationPayloads[i] = null; context.PreparationPayloads[message.ValidatorIndex] = payload; - byte[] hashData = context.EnsureHeader().GetSignData(neoSystem.Settings.Magic); + 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(context.CommitPayloads[i]).Signature, context.Validators[i])) diff --git a/src/DBFTPlugin/DBFTPlugin.cs b/src/DBFTPlugin/DBFTPlugin.cs index 6336959d5..84f709a89 100644 --- a/src/DBFTPlugin/DBFTPlugin.cs +++ b/src/DBFTPlugin/DBFTPlugin.cs @@ -30,7 +30,7 @@ protected override void Configure() protected override void OnSystemLoaded(NeoSystem system) { - if (system.Settings.Magic != settings.Network) return; + if (system.Settings.Network != settings.Network) return; neoSystem = system; neoSystem.ServiceAdded += NeoSystem_ServiceAdded; } diff --git a/src/Directory.Build.props b/src/Directory.Build.props index cf3ab0ab8..b5de3fe39 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -15,7 +15,7 @@ - + diff --git a/src/OracleService/OracleService.cs b/src/OracleService/OracleService.cs index 4afb0e67d..609722285 100644 --- a/src/OracleService/OracleService.cs +++ b/src/OracleService/OracleService.cs @@ -56,7 +56,7 @@ protected override void Configure() protected override void OnSystemLoaded(NeoSystem system) { - if (system.Settings.Magic != Settings.Default.Network) return; + if (system.Settings.Network != Settings.Default.Network) return; System = system; System.ServiceAdded += NeoSystem_ServiceAdded; RpcServerPlugin.RegisterMethods(this, Settings.Default.Network); @@ -139,7 +139,7 @@ private void OnStop() void IPersistencePlugin.OnPersist(NeoSystem system, Block block, DataCache snapshot, IReadOnlyList applicationExecutedList) { - if (system.Settings.Magic != Settings.Default.Network) return; + if (system.Settings.Network != Settings.Default.Network) return; if (stopped || !started) return; if (!CheckOracleAvaiblable(snapshot, out ECPoint[] oracles) || !CheckOracleAccount(wallet, oracles)) OnStop(); @@ -270,8 +270,8 @@ private async Task ProcessRequestAsync(DataCache snapshot, OracleRequest req) var oraclePub = account.GetKey()?.PublicKey; if (!account.HasKey || account.Lock || !oraclePublicKeys.Contains(oraclePub)) continue; - var txSign = responseTx.Sign(account.GetKey(), System.Settings.Magic); - var backTxSign = backupTx.Sign(account.GetKey(), System.Settings.Magic); + var txSign = responseTx.Sign(account.GetKey(), System.Settings.Network); + var backTxSign = backupTx.Sign(account.GetKey(), System.Settings.Network); AddResponseTxSign(snapshot, requestId, oraclePub, txSign, responseTx, backupTx, backTxSign); tasks.Add(SendResponseSignatureAsync(requestId, txSign, account.GetKey())); @@ -417,13 +417,13 @@ private void AddResponseTxSign(DataCache snapshot, ulong requestId, ECPoint orac if (responseTx != null) { task.Tx = responseTx; - var data = task.Tx.GetSignData(System.Settings.Magic); + var data = task.Tx.GetSignData(System.Settings.Network); task.Signs.Where(p => !Crypto.VerifySignature(data, p.Value, p.Key)).ForEach(p => task.Signs.Remove(p.Key, out _)); } if (backupTx != null) { task.BackupTx = backupTx; - var data = task.BackupTx.GetSignData(System.Settings.Magic); + var data = task.BackupTx.GetSignData(System.Settings.Network); task.BackupSigns.Where(p => !Crypto.VerifySignature(data, p.Value, p.Key)).ForEach(p => task.BackupSigns.Remove(p.Key, out _)); task.BackupSigns.TryAdd(oraclePub, backupSign); } @@ -434,9 +434,9 @@ private void AddResponseTxSign(DataCache snapshot, ulong requestId, ECPoint orac return; } - if (Crypto.VerifySignature(task.Tx.GetSignData(System.Settings.Magic), sign, oraclePub)) + if (Crypto.VerifySignature(task.Tx.GetSignData(System.Settings.Network), sign, oraclePub)) task.Signs.TryAdd(oraclePub, sign); - else if (Crypto.VerifySignature(task.BackupTx.GetSignData(System.Settings.Magic), sign, oraclePub)) + else if (Crypto.VerifySignature(task.BackupTx.GetSignData(System.Settings.Network), sign, oraclePub)) task.BackupSigns.TryAdd(oraclePub, sign); else throw new RpcException(-100, "Invalid response transaction sign"); diff --git a/src/RpcClient/TransactionManager.cs b/src/RpcClient/TransactionManager.cs index 3a1b39f13..26a4e539d 100644 --- a/src/RpcClient/TransactionManager.cs +++ b/src/RpcClient/TransactionManager.cs @@ -45,7 +45,7 @@ private class SignItem { public Contract Contract; public HashSet KeyPa public TransactionManager(Transaction tx, RpcClient rpcClient) { this.tx = tx; - this.context = new ContractParametersContext(null, tx); + this.context = new ContractParametersContext(null, tx, rpcClient.protocolSettings.Network); this.rpcClient = rpcClient; } @@ -165,7 +165,7 @@ public async Task SignAsync() { foreach (var key in signStore[i].KeyPairs) { - byte[] signature = Tx.Sign(key, rpcClient.protocolSettings.Magic); + byte[] signature = Tx.Sign(key, rpcClient.protocolSettings.Network); if (!context.AddSignature(signStore[i].Contract, key.PublicKey, signature)) { throw new Exception("AddSignature failed!"); diff --git a/src/RpcNep17Tracker/RpcNep17Tracker.cs b/src/RpcNep17Tracker/RpcNep17Tracker.cs index 8b7ef2ea6..49310a97c 100644 --- a/src/RpcNep17Tracker/RpcNep17Tracker.cs +++ b/src/RpcNep17Tracker/RpcNep17Tracker.cs @@ -37,9 +37,9 @@ public class RpcNep17Tracker : Plugin, IPersistencePlugin protected override void OnSystemLoaded(NeoSystem system) { - if (system.Settings.Magic != _network) return; + if (system.Settings.Network != _network) return; System = system; - string path = string.Format(_dbPath, system.Settings.Magic.ToString("X8")); + string path = string.Format(_dbPath, system.Settings.Network.ToString("X8")); _db = DB.Open(GetFullPath(path), new Options { CreateIfMissing = true }); RpcServerPlugin.RegisterMethods(this, _network); } @@ -164,7 +164,7 @@ private void HandleNotification(DataCache snapshot, IVerifiable scriptContainer, void IPersistencePlugin.OnPersist(NeoSystem system, Block block, DataCache snapshot, IReadOnlyList applicationExecutedList) { - if (system.Settings.Magic != _network) return; + if (system.Settings.Network != _network) return; // Start freshly with a new DBCache for each block. ResetBatch(); Dictionary nep17BalancesChanged = new Dictionary(); @@ -211,7 +211,7 @@ void IPersistencePlugin.OnPersist(NeoSystem system, Block block, DataCache snaps void IPersistencePlugin.OnCommit(NeoSystem system, Block block, DataCache snapshot) { - if (system.Settings.Magic != _network) return; + if (system.Settings.Network != _network) return; _db.Write(WriteOptions.Default, _writeBatch); } diff --git a/src/RpcServer/RpcServer.Node.cs b/src/RpcServer/RpcServer.Node.cs index 4f00bc7e5..371eaefda 100644 --- a/src/RpcServer/RpcServer.Node.cs +++ b/src/RpcServer/RpcServer.Node.cs @@ -65,7 +65,7 @@ protected virtual JObject GetVersion(JArray _params) json["wsport"] = localNode.ListenerWsPort; json["nonce"] = LocalNode.Nonce; json["useragent"] = LocalNode.UserAgent; - json["magic"] = system.Settings.Magic; + json["network"] = system.Settings.Network; return json; } diff --git a/src/RpcServer/RpcServer.Wallet.cs b/src/RpcServer/RpcServer.Wallet.cs index 4ed5b059c..b19d8c653 100644 --- a/src/RpcServer/RpcServer.Wallet.cs +++ b/src/RpcServer/RpcServer.Wallet.cs @@ -185,7 +185,7 @@ private void ProcessInvokeWithWallet(JObject result, Signers signers = null) result["exception"] = GetExceptionMessage(e); return; } - ContractParametersContext context = new(system.StoreView, tx); + ContractParametersContext context = new ContractParametersContext(system.StoreView, tx, settings.Network); wallet.Sign(context); if (context.Completed) { @@ -224,7 +224,7 @@ protected virtual JObject SendFrom(JArray _params) if (tx == null) throw new RpcException(-300, "Insufficient funds"); - ContractParametersContext transContext = new ContractParametersContext(snapshot, tx); + ContractParametersContext transContext = new ContractParametersContext(snapshot, tx, settings.Network); wallet.Sign(transContext); if (!transContext.Completed) return transContext.ToJson(); @@ -275,7 +275,7 @@ protected virtual JObject SendMany(JArray _params) if (tx == null) throw new RpcException(-300, "Insufficient funds"); - ContractParametersContext transContext = new ContractParametersContext(snapshot, tx); + ContractParametersContext transContext = new ContractParametersContext(snapshot, tx, settings.Network); wallet.Sign(transContext); if (!transContext.Completed) return transContext.ToJson(); @@ -314,7 +314,7 @@ protected virtual JObject SendToAddress(JArray _params) if (tx == null) throw new RpcException(-300, "Insufficient funds"); - ContractParametersContext transContext = new ContractParametersContext(snapshot, tx); + ContractParametersContext transContext = new ContractParametersContext(snapshot, tx, settings.Network); wallet.Sign(transContext); if (!transContext.Completed) return transContext.ToJson(); @@ -393,7 +393,7 @@ private JObject GetVerificationResult(UInt160 scriptHash, ContractParameter[] ar private JObject SignAndRelay(DataCache snapshot, Transaction tx) { - ContractParametersContext context = new ContractParametersContext(snapshot, tx); + ContractParametersContext context = new ContractParametersContext(snapshot, tx, settings.Network); wallet.Sign(context); if (context.Completed) { diff --git a/src/RpcServer/RpcServerPlugin.cs b/src/RpcServer/RpcServerPlugin.cs index 15c6a698c..8ebe76664 100644 --- a/src/RpcServer/RpcServerPlugin.cs +++ b/src/RpcServer/RpcServerPlugin.cs @@ -29,7 +29,7 @@ public override void Dispose() protected override void OnSystemLoaded(NeoSystem system) { - RpcServerSettings s = settings.Servers.FirstOrDefault(p => p.Network == system.Settings.Magic); + RpcServerSettings s = settings.Servers.FirstOrDefault(p => p.Network == system.Settings.Network); if (s is null) return; RpcServer server = new RpcServer(system, s); diff --git a/src/StateService/StatePlugin.cs b/src/StateService/StatePlugin.cs index 6e7631a3c..5c78dfbd7 100644 --- a/src/StateService/StatePlugin.cs +++ b/src/StateService/StatePlugin.cs @@ -38,9 +38,9 @@ protected override void Configure() protected override void OnSystemLoaded(NeoSystem system) { - if (system.Settings.Magic != Settings.Default.Network) return; + if (system.Settings.Network != Settings.Default.Network) return; System = system; - Store = System.ActorSystem.ActorOf(StateStore.Props(this, string.Format(Settings.Default.Path, system.Settings.Magic.ToString("X8")))); + Store = System.ActorSystem.ActorOf(StateStore.Props(this, string.Format(Settings.Default.Path, system.Settings.Network.ToString("X8")))); System.ServiceAdded += NeoSystem_ServiceAdded; RpcServerPlugin.RegisterMethods(this, Settings.Default.Network); } @@ -73,14 +73,14 @@ public override void Dispose() void IPersistencePlugin.OnPersist(NeoSystem system, Block block, DataCache snapshot, IReadOnlyList applicationExecutedList) { - if (system.Settings.Magic != Settings.Default.Network) return; + if (system.Settings.Network != Settings.Default.Network) return; StateStore.Singleton.UpdateLocalStateRoot(block.Index, snapshot.GetChangeSet().Where(p => p.State != TrackState.None).Where(p => p.Key.Id != NativeContract.Ledger.Id).ToList()); } [ConsoleCommand("start states", Category = "StateService", Description = "Start as a state verifier if wallet is open")] private void OnStartVerifyingState() { - if (System is null || System.Settings.Magic != Settings.Default.Network) throw new InvalidOperationException("Network doesn't match"); + if (System is null || System.Settings.Network != Settings.Default.Network) throw new InvalidOperationException("Network doesn't match"); Start(walletProvider.GetWallet()); } @@ -102,7 +102,7 @@ public void Start(Wallet wallet) [ConsoleCommand("state root", Category = "StateService", Description = "Get state root by index")] private void OnGetStateRoot(uint index) { - if (System is null || System.Settings.Magic != Settings.Default.Network) throw new InvalidOperationException("Network doesn't match"); + if (System is null || System.Settings.Network != Settings.Default.Network) throw new InvalidOperationException("Network doesn't match"); using var snapshot = StateStore.Singleton.GetSnapshot(); StateRoot state_root = snapshot.GetStateRoot(index); if (state_root is null) @@ -114,14 +114,14 @@ private void OnGetStateRoot(uint index) [ConsoleCommand("state height", Category = "StateService", Description = "Get current state root index")] private void OnGetStateHeight() { - if (System is null || System.Settings.Magic != Settings.Default.Network) throw new InvalidOperationException("Network doesn't match"); + if (System is null || System.Settings.Network != Settings.Default.Network) throw new InvalidOperationException("Network doesn't match"); Console.WriteLine($"LocalRootIndex: {StateStore.Singleton.LocalRootIndex}, ValidatedRootIndex: {StateStore.Singleton.ValidatedRootIndex}"); } [ConsoleCommand("get proof", Category = "StateService", Description = "Get proof of key and contract hash")] private void OnGetProof(UInt256 root_hash, UInt160 script_hash, string key) { - if (System is null || System.Settings.Magic != Settings.Default.Network) throw new InvalidOperationException("Network doesn't match"); + if (System is null || System.Settings.Network != Settings.Default.Network) throw new InvalidOperationException("Network doesn't match"); try { Console.WriteLine(GetProof(root_hash, script_hash, Convert.FromBase64String(key))); diff --git a/src/StateService/Verification/VerificationContext.cs b/src/StateService/Verification/VerificationContext.cs index 248bb5f0a..8e0234044 100644 --- a/src/StateService/Verification/VerificationContext.cs +++ b/src/StateService/Verification/VerificationContext.cs @@ -89,7 +89,7 @@ private ExtensiblePayload CreateVoteMessage() if (StateRoot is null) return null; if (!signatures.TryGetValue(myIndex, out byte[] sig)) { - sig = StateRoot.Sign(keyPair, StatePlugin.System.Settings.Magic); + sig = StateRoot.Sign(keyPair, StatePlugin.System.Settings.Network); signatures[myIndex] = sig; } return CreatePayload(MessageType.Vote, new Vote @@ -107,7 +107,7 @@ public bool AddSignature(int index, byte[] sig) if (signatures.ContainsKey(index)) return false; Utility.Log(nameof(VerificationContext), LogLevel.Info, $"vote received, height={rootIndex}, index={index}"); ECPoint validator = verifiers[index]; - byte[] hash_data = StateRoot?.GetSignData(StatePlugin.System.Settings.Magic); + byte[] hash_data = StateRoot?.GetSignData(StatePlugin.System.Settings.Network); if (hash_data is null || !Crypto.VerifySignature(hash_data, sig, validator)) { Utility.Log(nameof(VerificationContext), LogLevel.Info, "incorrect vote, invalid signature"); @@ -123,7 +123,7 @@ public bool CheckSignatures() if (StateRoot.Witness is null) { Contract contract = Contract.CreateMultiSigContract(M, verifiers); - ContractParametersContext sc = new(StatePlugin.System.StoreView, StateRoot); + ContractParametersContext sc = new(StatePlugin.System.StoreView, StateRoot, StatePlugin.System.Settings.Network); for (int i = 0, j = 0; i < verifiers.Length && j < M; i++) { if (!signatures.TryGetValue(i, out byte[] sig)) continue; @@ -157,7 +157,7 @@ private ExtensiblePayload CreatePayload(MessageType type, ISerializable payload, Sender = Contract.CreateSignatureRedeemScript(verifiers[MyIndex]).ToScriptHash(), Data = data, }; - ContractParametersContext sc = new ContractParametersContext(StatePlugin.System.StoreView, msg); + ContractParametersContext sc = new ContractParametersContext(StatePlugin.System.StoreView, msg, StatePlugin.System.Settings.Network); wallet.Sign(sc); msg.Witness = sc.GetWitnesses()[0]; return msg; diff --git a/src/StatesDumper/StatesDumper.cs b/src/StatesDumper/StatesDumper.cs index 3b7621e48..4a0dbf5e1 100644 --- a/src/StatesDumper/StatesDumper.cs +++ b/src/StatesDumper/StatesDumper.cs @@ -26,7 +26,7 @@ protected override void Configure() protected override void OnSystemLoaded(NeoSystem system) { - systems.Add(system.Settings.Magic, system); + systems.Add(system.Settings.Network, system); } /// @@ -49,7 +49,7 @@ private void OnDumpStorage(uint network, UInt160 key = null) void IPersistencePlugin.OnPersist(NeoSystem system, Block block, DataCache snapshot, IReadOnlyList applicationExecutedList) { if (Settings.Default.PersistAction.HasFlag(PersistActions.StorageChanges)) - OnPersistStorage(system.Settings.Magic, snapshot); + OnPersistStorage(system.Settings.Network, snapshot); } private void OnPersistStorage(uint network, DataCache snapshot) @@ -101,7 +101,7 @@ private void OnPersistStorage(uint network, DataCache snapshot) void IPersistencePlugin.OnCommit(NeoSystem system, Block block, DataCache snapshot) { if (Settings.Default.PersistAction.HasFlag(PersistActions.StorageChanges)) - OnCommitStorage(system.Settings.Magic, snapshot); + OnCommitStorage(system.Settings.Network, snapshot); } void OnCommitStorage(uint network, DataCache snapshot) diff --git a/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs b/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs index f6dd24c07..8f54f4492 100644 --- a/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs +++ b/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs @@ -165,7 +165,7 @@ await txManager var tx = txManager.Tx; byte[] signature = tx.Witnesses[0].InvocationScript.Skip(2).ToArray(); - Assert.IsTrue(Crypto.VerifySignature(tx.GetSignData(client.protocolSettings.Magic), signature, keyPair1.PublicKey)); + Assert.IsTrue(Crypto.VerifySignature(tx.GetSignData(client.protocolSettings.Network), signature, keyPair1.PublicKey)); // verify network fee and system fee Assert.AreEqual(100000000/*Mock*/, tx.NetworkFee); Assert.AreEqual(100, tx.SystemFee); From a465c0a2c256c02ae8152f7cd1c6a9d04dcf32fd Mon Sep 17 00:00:00 2001 From: Owen Zhang <38493437+superboyiii@users.noreply.github.com> Date: Thu, 1 Apr 2021 15:07:27 +0800 Subject: [PATCH 25/30] Sync to Neo v3.0.0-CI01259 (#578) --- src/Directory.Build.props | 2 +- src/RpcClient/Models/RpcVersion.cs | 6 +++--- tests/Neo.Network.RPC.Tests/RpcTestCases.json | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index b5de3fe39..406757a43 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -15,7 +15,7 @@ - + diff --git a/src/RpcClient/Models/RpcVersion.cs b/src/RpcClient/Models/RpcVersion.cs index 06e7d7056..5a3e54cd2 100644 --- a/src/RpcClient/Models/RpcVersion.cs +++ b/src/RpcClient/Models/RpcVersion.cs @@ -4,7 +4,7 @@ namespace Neo.Network.RPC.Models { public class RpcVersion { - public uint Magic { get; set; } + public uint Network { get; set; } public int TcpPort { get; set; } @@ -18,7 +18,7 @@ public class RpcVersion public JObject ToJson() { JObject json = new JObject(); - json["magic"] = Magic; + json["network"] = Network; json["tcpport"] = TcpPort; json["wsport"] = WsPort; json["nonce"] = Nonce; @@ -30,7 +30,7 @@ public static RpcVersion FromJson(JObject json) { return new RpcVersion { - Magic = (uint)json["magic"].AsNumber(), + Network = (uint)json["network"].AsNumber(), TcpPort = (int)json["tcpport"].AsNumber(), WsPort = (int)json["wsport"].AsNumber(), Nonce = (uint)json["nonce"].AsNumber(), diff --git a/tests/Neo.Network.RPC.Tests/RpcTestCases.json b/tests/Neo.Network.RPC.Tests/RpcTestCases.json index d47ed1a8a..6895151af 100644 --- a/tests/Neo.Network.RPC.Tests/RpcTestCases.json +++ b/tests/Neo.Network.RPC.Tests/RpcTestCases.json @@ -2450,11 +2450,11 @@ "jsonrpc": "2.0", "id": 1, "result": { - "magic": 0, + "network": 0, "tcpport": 20333, "wsport": 20334, "nonce": 592651621, - "useragent": "/Neo:3.0.0-preview1/" + "useragent": "/Neo:3.0.0-rc1/" } } }, From 43f08edbd16196e26f5acab61c93eee0a15c39d6 Mon Sep 17 00:00:00 2001 From: ZhangTao Date: Fri, 9 Apr 2021 14:27:36 +0800 Subject: [PATCH 26/30] [OracleService] Update neofs api (#580) * update neofs api * default neofs node config --- src/OracleService/OracleService.csproj | 2 +- src/OracleService/OracleService/config.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OracleService/OracleService.csproj b/src/OracleService/OracleService.csproj index c65ad1468..d6580de1a 100644 --- a/src/OracleService/OracleService.csproj +++ b/src/OracleService/OracleService.csproj @@ -6,7 +6,7 @@ - + diff --git a/src/OracleService/OracleService/config.json b/src/OracleService/OracleService/config.json index 83f690ac5..7bad690bb 100644 --- a/src/OracleService/OracleService/config.json +++ b/src/OracleService/OracleService/config.json @@ -9,7 +9,7 @@ "Timeout": 5000 }, "NeoFS": { - "EndPoint": "127.0.0.1:8080", + "EndPoint": "http://127.0.0.1:8080", "Timeout": 15000 }, "AutoStart": false From 057ff466645ee55c59d00a1231300705ea03511e Mon Sep 17 00:00:00 2001 From: Shargon Date: Mon, 12 Apr 2021 10:24:09 +0200 Subject: [PATCH 27/30] Add user agent header (#581) * Add user agent * Update OracleHttpsProtocol.cs * Update src/OracleService/Protocols/OracleHttpsProtocol.cs Co-authored-by: Owen Zhang <38493437+superboyiii@users.noreply.github.com> Co-authored-by: Erik Zhang Co-authored-by: Owen Zhang <38493437+superboyiii@users.noreply.github.com> --- src/OracleService/Protocols/OracleHttpsProtocol.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/OracleService/Protocols/OracleHttpsProtocol.cs b/src/OracleService/Protocols/OracleHttpsProtocol.cs index 9791f8520..f7b2b4b34 100644 --- a/src/OracleService/Protocols/OracleHttpsProtocol.cs +++ b/src/OracleService/Protocols/OracleHttpsProtocol.cs @@ -3,6 +3,8 @@ using System.Linq; using System.Net; using System.Net.Http; +using System.Net.Http.Headers; +using System.Reflection; using System.Threading; using System.Threading.Tasks; @@ -12,6 +14,13 @@ class OracleHttpsProtocol : IOracleProtocol { private readonly HttpClient client = new HttpClient(); + public OracleHttpsProtocol() + { + CustomAttributeData attribute = Assembly.GetExecutingAssembly().CustomAttributes.First(p => p.AttributeType == typeof(AssemblyInformationalVersionAttribute)); + string version = (string)attribute.ConstructorArguments[0].Value; + client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("NeoOracleService", version)); + } + public void Configure() { client.DefaultRequestHeaders.Accept.Clear(); From 4359882d2b72838ad915f0d5ead0322589c4f443 Mon Sep 17 00:00:00 2001 From: Shargon Date: Tue, 20 Apr 2021 10:49:36 +0200 Subject: [PATCH 28/30] Process iterator in RPC result (#583) * Process iterator * Fix * Use while * Preserve type * Update src/RpcServer/RpcServer.SmartContract.cs Co-authored-by: Satoshi Chou <82646971+satoshichou@users.noreply.github.com> * Update src/RpcServer/RpcServer.SmartContract.cs * Include other items in warning * < instead of <= * Optimize * Rename Co-authored-by: Erik Zhang Co-authored-by: Satoshi Chou <82646971+satoshichou@users.noreply.github.com> --- src/RpcServer/RpcServer.SmartContract.cs | 25 +++++++++++++++++++++--- src/RpcServer/RpcServer/config.json | 1 + src/RpcServer/Settings.cs | 3 +++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/RpcServer/RpcServer.SmartContract.cs b/src/RpcServer/RpcServer.SmartContract.cs index b373175ec..8af239ee8 100644 --- a/src/RpcServer/RpcServer.SmartContract.cs +++ b/src/RpcServer/RpcServer.SmartContract.cs @@ -7,8 +7,10 @@ using Neo.Network.P2P.Payloads; using Neo.Persistence; using Neo.SmartContract; +using Neo.SmartContract.Iterators; using Neo.SmartContract.Native; using Neo.VM; +using Neo.VM.Types; using Neo.Wallets; using System; using System.IO; @@ -65,7 +67,7 @@ private JObject GetInvokeResult(byte[] script, Signers signers = null) Transaction tx = signers == null ? null : new Transaction { Signers = signers.GetSigners(), - Attributes = Array.Empty(), + Attributes = System.Array.Empty(), Witnesses = signers.Witnesses, }; using ApplicationEngine engine = ApplicationEngine.Run(script, system.StoreView, container: tx, settings: system.Settings, gas: settings.MaxGasInvoke); @@ -76,11 +78,11 @@ private JObject GetInvokeResult(byte[] script, Signers signers = null) json["exception"] = GetExceptionMessage(engine.FaultException); try { - json["stack"] = new JArray(engine.ResultStack.Select(p => p.ToJson())); + json["stack"] = new JArray(engine.ResultStack.Select(p => ToJson(p, settings.MaxIteratorResultItems))); } catch (InvalidOperationException) { - json["stack"] = "error: recursive reference"; + json["stack"] = "error: invalid operation"; } if (engine.State != VMState.FAULT) { @@ -89,6 +91,23 @@ private JObject GetInvokeResult(byte[] script, Signers signers = null) return json; } + private static JObject ToJson(StackItem item, int max) + { + JObject json = item.ToJson(); + if (item is InteropInterface interopInterface && interopInterface.GetInterface() is IIterator iterator) + { + JArray array = new(); + while (max > 0 && iterator.Next()) + { + array.Add(iterator.Value().ToJson()); + max--; + } + json["iterator"] = array; + json["truncated"] = iterator.Next(); + } + return json; + } + private static Signers SignersFromJson(JArray _params, ProtocolSettings settings) { var ret = new Signers(_params.Select(u => new Signer() diff --git a/src/RpcServer/RpcServer/config.json b/src/RpcServer/RpcServer/config.json index 1e9d77dd7..0f65fdde4 100644 --- a/src/RpcServer/RpcServer/config.json +++ b/src/RpcServer/RpcServer/config.json @@ -13,6 +13,7 @@ "MaxGasInvoke": 20, "MaxFee": 0.1, "MaxConcurrentConnections": 40, + "MaxIteratorResultItems": 100, "DisabledMethods": [ "openwallet" ] } ] diff --git a/src/RpcServer/Settings.cs b/src/RpcServer/Settings.cs index 5ea890d8d..803bdae0d 100644 --- a/src/RpcServer/Settings.cs +++ b/src/RpcServer/Settings.cs @@ -30,6 +30,7 @@ public record RpcServerSettings public string RpcPass { get; init; } public long MaxGasInvoke { get; init; } public long MaxFee { get; init; } + public int MaxIteratorResultItems { get; init; } public string[] DisabledMethods { get; init; } public static RpcServerSettings Default { get; } = new RpcServerSettings @@ -41,6 +42,7 @@ public record RpcServerSettings MaxGasInvoke = (long)new BigDecimal(10M, NativeContract.GAS.Decimals).Value, MaxFee = (long)new BigDecimal(0.1M, NativeContract.GAS.Decimals).Value, TrustedAuthorities = Array.Empty(), + MaxIteratorResultItems = 100, DisabledMethods = Array.Empty(), MaxConcurrentConnections = 40, }; @@ -57,6 +59,7 @@ public record RpcServerSettings RpcPass = section.GetSection("RpcPass").Value, MaxGasInvoke = (long)new BigDecimal(section.GetValue("MaxGasInvoke", Default.MaxGasInvoke), NativeContract.GAS.Decimals).Value, MaxFee = (long)new BigDecimal(section.GetValue("MaxFee", Default.MaxFee), NativeContract.GAS.Decimals).Value, + MaxIteratorResultItems = section.GetValue("MaxIteratorResultItems", Default.MaxIteratorResultItems), DisabledMethods = section.GetSection("DisabledMethods").GetChildren().Select(p => p.Get()).ToArray(), MaxConcurrentConnections = section.GetValue("MaxConcurrentConnections", Default.MaxConcurrentConnections), }; From fe8f26a42814364729ac5be1b2fb058d5b6d2ebe Mon Sep 17 00:00:00 2001 From: HaoqiangZhang Date: Thu, 29 Apr 2021 09:10:27 +0800 Subject: [PATCH 29/30] sync to Neo 3.0.0-CI01272 (#585) --- src/Directory.Build.props | 2 +- tests/Neo.Network.RPC.Tests/RpcTestCases.json | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 406757a43..64c392100 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -15,7 +15,7 @@ - + diff --git a/tests/Neo.Network.RPC.Tests/RpcTestCases.json b/tests/Neo.Network.RPC.Tests/RpcTestCases.json index 6895151af..ae039d882 100644 --- a/tests/Neo.Network.RPC.Tests/RpcTestCases.json +++ b/tests/Neo.Network.RPC.Tests/RpcTestCases.json @@ -364,6 +364,7 @@ "manifest": { "name": "GasToken", "groups": [], + "features": {}, "supportedstandards": [ "NEP-17" ], @@ -484,6 +485,7 @@ "manifest": { "name": "GasToken", "groups": [], + "features": {}, "supportedstandards": [ "NEP-17" ], @@ -604,6 +606,7 @@ "manifest": { "name": "NeoToken", "groups": [], + "features": {}, "supportedstandards": [ "NEP-17" ], @@ -820,6 +823,7 @@ "manifest": { "name": "NeoToken", "groups": [], + "features": {}, "supportedstandards": [ "NEP-17" ], @@ -1036,6 +1040,7 @@ "manifest": { "name": "ContractManagement", "groups": [], + "features": {}, "supportedstandards": [], "abi": { "methods": [ @@ -1204,6 +1209,7 @@ "manifest": { "name": "LedgerContract", "groups": [], + "features": {}, "supportedstandards": [], "abi": { "methods": [ @@ -1300,6 +1306,7 @@ "manifest": { "name": "NeoToken", "groups": [], + "features": {}, "supportedstandards": [ "NEP-17" ], @@ -1503,6 +1510,7 @@ "manifest": { "name": "GasToken", "groups": [], + "features": {}, "supportedstandards": [ "NEP-17" ], @@ -1610,6 +1618,7 @@ "manifest": { "name": "PolicyContract", "groups": [], + "features": {}, "supportedstandards": [], "abi": { "methods": [ @@ -1790,6 +1799,7 @@ "manifest": { "name": "RoleManagement", "groups": [], + "features": {}, "supportedstandards": [], "abi": { "methods": [ @@ -1852,6 +1862,7 @@ "manifest": { "name": "OracleContract", "groups": [], + "features": {}, "supportedstandards": [], "abi": { "methods": [ @@ -1959,6 +1970,7 @@ "manifest": { "name": "NameService", "groups": [], + "features": {}, "supportedstandards": [], "abi": { "methods": [ From 900d0d9aea139a6954d31b1d489c0dfab176233f Mon Sep 17 00:00:00 2001 From: ZhangTao Date: Sat, 1 May 2021 22:24:47 +0800 Subject: [PATCH 30/30] [RC2] Update neo and neofs api (#588) * update neo and neofs api * use neo jason path * Optimize Co-authored-by: Erik Zhang --- src/Directory.Build.props | 4 +-- src/OracleService/OracleService.cs | 10 +++--- src/OracleService/OracleService.csproj | 2 +- .../Protocols/OracleNeoFSProtocol.cs | 11 +++--- src/RpcClient/TransactionManagerFactory.cs | 2 +- .../UT_OracleService.cs | 36 +++++++++---------- 6 files changed, 31 insertions(+), 34 deletions(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 64c392100..72086262f 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -3,7 +3,7 @@ 3.0.0 - rc1 + rc2 net5.0 Neo.Plugins The Neo Project @@ -15,7 +15,7 @@ - + diff --git a/src/OracleService/OracleService.cs b/src/OracleService/OracleService.cs index 609722285..cead0dbd2 100644 --- a/src/OracleService/OracleService.cs +++ b/src/OracleService/OracleService.cs @@ -23,8 +23,6 @@ using System.Text; using System.Threading; using System.Threading.Tasks; -using NJArray = Newtonsoft.Json.Linq.JArray; -using NJObject = Newtonsoft.Json.Linq.JObject; namespace Neo.Plugins { @@ -327,7 +325,7 @@ public static Transaction CreateResponseTx(DataCache snapshot, OracleRequest req { Version = 0, Nonce = unchecked((uint)response.Id), - ValidUntilBlock = requestTx.BlockIndex + Transaction.MaxValidUntilBlockIncrement, + ValidUntilBlock = requestTx.BlockIndex + settings.MaxValidUntilBlockIncrement, Signers = new[] { new Signer @@ -453,9 +451,9 @@ public static byte[] Filter(string input, string filterArgs) if (string.IsNullOrEmpty(filterArgs)) return Utility.StrictUTF8.GetBytes(input); - NJObject beforeObject = NJObject.Parse(input); - NJArray afterObjects = new NJArray(beforeObject.SelectTokens(filterArgs)); - return Utility.StrictUTF8.GetBytes(afterObjects.ToString(Newtonsoft.Json.Formatting.None)); + JObject beforeObject = JObject.Parse(input); + JArray afterObjects = beforeObject.JsonPath(filterArgs); + return afterObjects.ToByteArray(false); } private bool CheckTxSign(DataCache snapshot, Transaction tx, ConcurrentDictionary OracleSigns) diff --git a/src/OracleService/OracleService.csproj b/src/OracleService/OracleService.csproj index d6580de1a..2d11766bf 100644 --- a/src/OracleService/OracleService.csproj +++ b/src/OracleService/OracleService.csproj @@ -6,7 +6,7 @@ - + diff --git a/src/OracleService/Protocols/OracleNeoFSProtocol.cs b/src/OracleService/Protocols/OracleNeoFSProtocol.cs index 98fd0218c..9e6cef475 100644 --- a/src/OracleService/Protocols/OracleNeoFSProtocol.cs +++ b/src/OracleService/Protocols/OracleNeoFSProtocol.cs @@ -1,6 +1,5 @@ using Neo.Cryptography.ECC; using Neo.FileStorage.API.Client; -using Neo.FileStorage.API.Client.ObjectParams; using Neo.FileStorage.API.Cryptography; using Neo.FileStorage.API.Refs; using Neo.IO.Json; @@ -88,7 +87,7 @@ private Task GetAsync(Uri uri, string host, CancellationToken cancellati private static async Task GetPayloadAsync(Client client, Address addr, CancellationToken cancellation) { - Object obj = await client.GetObject(new GetObjectParams() { Address = addr }, new CallOptions { Ttl = 2 }, cancellation); + Object obj = await client.GetObject(addr, options: new CallOptions { Ttl = 2 }, context: cancellation); return obj.Payload.ToString(Utility.StrictUTF8); } @@ -96,13 +95,13 @@ private static async Task GetRangeAsync(Client client, Address addr, str { if (ps.Length == 0) throw new FormatException("missing object range (expected 'Offset|Length')"); Range range = ParseRange(ps[0]); - var res = await client.GetObjectPayloadRangeData(new RangeDataParams() { Address = addr, Range = range }, new CallOptions { Ttl = 2 }, cancellation); + var res = await client.GetObjectPayloadRangeData(addr, range, options: new CallOptions { Ttl = 2 }, context: cancellation); return Utility.StrictUTF8.GetString(res); } private static async Task GetHeaderAsync(Client client, Address addr, CancellationToken cancellation) { - var obj = await client.GetObjectHeader(new ObjectHeaderParams() { Address = addr }, new CallOptions { Ttl = 2 }, cancellation); + var obj = await client.GetObjectHeader(addr, options: new CallOptions { Ttl = 2 }, context: cancellation); return obj.ToJson().ToString(); } @@ -110,11 +109,11 @@ private static async Task GetHashAsync(Client client, Address addr, stri { if (ps.Length == 0 || ps[0] == "") { - Object obj = await client.GetObjectHeader(new ObjectHeaderParams() { Address = addr }, new CallOptions { Ttl = 2 }, cancellation); + Object obj = await client.GetObjectHeader(addr, options: new CallOptions { Ttl = 2 }, context: cancellation); return $"\"{new UInt256(obj.PayloadChecksum.Sum.ToByteArray())}\""; } Range range = ParseRange(ps[0]); - List hashes = await client.GetObjectPayloadRangeHash(new RangeChecksumParams() { Address = addr, Ranges = new List() { range }, Type = ChecksumType.Sha256, Salt = Array.Empty() }, new CallOptions { Ttl = 2 }, cancellation); + List hashes = await client.GetObjectPayloadRangeHash(addr, new List() { range }, ChecksumType.Sha256, Array.Empty(), new CallOptions { Ttl = 2 }, cancellation); if (hashes.Count == 0) throw new Exception("empty response, object range is invalid (expected 'Offset|Length')"); return $"\"{new UInt256(hashes[0])}\""; } diff --git a/src/RpcClient/TransactionManagerFactory.cs b/src/RpcClient/TransactionManagerFactory.cs index 0db55465a..6c60b5252 100644 --- a/src/RpcClient/TransactionManagerFactory.cs +++ b/src/RpcClient/TransactionManagerFactory.cs @@ -35,7 +35,7 @@ public async Task MakeTransactionAsync(byte[] script, Signer Nonce = (uint)new Random().Next(), Script = script, Signers = signers ?? Array.Empty(), - ValidUntilBlock = blockCount - 1 + Transaction.MaxValidUntilBlockIncrement, + ValidUntilBlock = blockCount - 1 + rpcClient.protocolSettings.MaxValidUntilBlockIncrement, SystemFee = invokeResult.GasConsumed, Attributes = attributes ?? Array.Empty(), }; diff --git a/tests/Neo.Plugins.OracleService.Tests/UT_OracleService.cs b/tests/Neo.Plugins.OracleService.Tests/UT_OracleService.cs index 4e658ce42..672ded757 100644 --- a/tests/Neo.Plugins.OracleService.Tests/UT_OracleService.cs +++ b/tests/Neo.Plugins.OracleService.Tests/UT_OracleService.cs @@ -20,40 +20,40 @@ public void TestSetup() public void TestFilter() { var json = @"{ - 'Stores': [ - 'Lambton Quay', - 'Willis Street' + ""Stores"": [ + ""Lambton Quay"", + ""Willis Street"" ], - 'Manufacturers': [ + ""Manufacturers"": [ { - 'Name': 'Acme Co', - 'Products': [ + ""Name"": ""Acme Co"", + ""Products"": [ { - 'Name': 'Anvil', - 'Price': 50 + ""Name"": ""Anvil"", + ""Price"": 50 } ] }, { - 'Name': 'Contoso', - 'Products': [ + ""Name"": ""Contoso"", + ""Products"": [ { - 'Name': 'Elbow Grease', - 'Price': 99.95 + ""Name"": ""Elbow Grease"", + ""Price"": 99.95 }, { - 'Name': 'Headlight Fluid', - 'Price': 4 + ""Name"": ""Headlight Fluid"", + ""Price"": 4 } ] } ] }"; - Assert.AreEqual(@"[""Acme Co""]", Utility.StrictUTF8.GetString(OracleService.Filter(json, "Manufacturers[0].Name"))); - Assert.AreEqual("[50]", Utility.StrictUTF8.GetString(OracleService.Filter(json, "Manufacturers[0].Products[0].Price"))); - Assert.AreEqual(@"[""Elbow Grease""]", Utility.StrictUTF8.GetString(OracleService.Filter(json, "Manufacturers[1].Products[0].Name"))); - Assert.AreEqual(@"[{""Name"":""Elbow Grease"",""Price"":99.95}]", Utility.StrictUTF8.GetString(OracleService.Filter(json, "Manufacturers[1].Products[0]"))); + Assert.AreEqual(@"[""Acme Co""]", Utility.StrictUTF8.GetString(OracleService.Filter(json, "$.Manufacturers[0].Name"))); + Assert.AreEqual("[50]", Utility.StrictUTF8.GetString(OracleService.Filter(json, "$.Manufacturers[0].Products[0].Price"))); + Assert.AreEqual(@"[""Elbow Grease""]", Utility.StrictUTF8.GetString(OracleService.Filter(json, "$.Manufacturers[1].Products[0].Name"))); + Assert.AreEqual(@"[{""Name"":""Elbow Grease"",""Price"":99.95}]", Utility.StrictUTF8.GetString(OracleService.Filter(json, "$.Manufacturers[1].Products[0]"))); } [TestMethod]