diff --git a/src/Neo.CLI/CLI/MainService.Block.cs b/src/Neo.CLI/CLI/MainService.Block.cs index 76a0be35bc..81f1d8f746 100644 --- a/src/Neo.CLI/CLI/MainService.Block.cs +++ b/src/Neo.CLI/CLI/MainService.Block.cs @@ -15,7 +15,6 @@ using Neo.Ledger; using Neo.Network.P2P; using Neo.Network.P2P.Payloads; -using Neo.SmartContract; using Neo.SmartContract.Native; using System; using System.Collections.Generic; @@ -193,7 +192,7 @@ private void WriteBlocks(uint start, uint count, string path, bool writeStart) { for (uint i = start; i <= end; i++) { - Block block = NativeContract.Ledger.GetBlock(NeoSystem.StoreView, i); + Block block = NativeContract.Ledger.GetBlock(NeoSystem.StoreView, i)!; byte[] array = block.ToArray(); fs.Write(BitConverter.GetBytes(array.Length), 0, sizeof(int)); fs.Write(array, 0, array.Length); @@ -220,11 +219,7 @@ private async Task ImportBlocksFromFile(bool verifyImport) blocksToImport.Add(blocksBeingImported.Current); } if (blocksToImport.Count == 0) break; - await NeoSystem.Blockchain.Ask(new Blockchain.Import - { - Blocks = blocksToImport, - Verify = verifyImport - }); + await NeoSystem.Blockchain.Ask(new Blockchain.Import(blocksToImport, verifyImport)); if (NeoSystem is null) return; } } diff --git a/src/Neo.CLI/CLI/MainService.Blockchain.cs b/src/Neo.CLI/CLI/MainService.Blockchain.cs index 3dd3331026..13c6b0ab0a 100644 --- a/src/Neo.CLI/CLI/MainService.Blockchain.cs +++ b/src/Neo.CLI/CLI/MainService.Blockchain.cs @@ -99,7 +99,7 @@ public void OnShowTransactionCommand(UInt256 hash) return; } - var block = NativeContract.Ledger.GetHeader(NeoSystem.StoreView, tx.BlockIndex); + var block = NativeContract.Ledger.GetHeader(NeoSystem.StoreView, tx.BlockIndex)!; var transactionDatetime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); transactionDatetime = transactionDatetime.AddMilliseconds(block.Timestamp).ToLocalTime(); @@ -126,20 +126,20 @@ public void OnShowTransactionCommand(UInt256 hash) foreach (var signer in tx.Transaction.Signers) { - if (signer.Rules.Length == 0) - ConsoleHelper.Info("", " Rules: ", "[]"); - else + if (signer.Rules?.Length > 0) ConsoleHelper.Info("", " Rules: ", $"[{string.Join(", ", signer.Rules.Select(s => $"\"{s.ToJson()}\""))}]"); + else + ConsoleHelper.Info("", " Rules: ", "[]"); ConsoleHelper.Info("", " Account: ", $"{signer.Account}"); ConsoleHelper.Info("", " Scopes: ", $"{signer.Scopes}"); - if (signer.AllowedContracts.Length == 0) - ConsoleHelper.Info("", " AllowedContracts: ", "[]"); - else + if (signer.AllowedContracts?.Length > 0) ConsoleHelper.Info("", " AllowedContracts: ", $"[{string.Join(", ", signer.AllowedContracts.Select(s => s.ToString()))}]"); - if (signer.AllowedGroups.Length == 0) - ConsoleHelper.Info("", " AllowedGroups: ", "[]"); else + ConsoleHelper.Info("", " AllowedContracts: ", "[]"); + if (signer.AllowedGroups?.Length > 0) ConsoleHelper.Info("", " AllowedGroups: ", $"[{string.Join(", ", signer.AllowedGroups.Select(s => s.ToString()))}]"); + else + ConsoleHelper.Info("", " AllowedGroups: ", "[]"); ConsoleHelper.Info("", " Size: ", $"{signer.Size} Byte(s)"); ConsoleHelper.Info(); } @@ -209,15 +209,17 @@ public void OnShowContractCommand(string nameOrHash) { ContractState? contract = null; NativeContract? nativeContract = null; - var isHash = UInt160.TryParse(nameOrHash, out var scriptHash); - if (isHash) + bool isHash; + if (UInt160.TryParse(nameOrHash, out var scriptHash)) { + isHash = true; contract = NativeContract.ContractManagement.GetContract(NeoSystem.StoreView, scriptHash); if (contract is null) nativeContract = NativeContract.Contracts.SingleOrDefault(s => s.Hash == scriptHash); } else { + isHash = false; nativeContract = NativeContract.Contracts.SingleOrDefault(s => s.Name.Equals(nameOrHash, StringComparison.InvariantCultureIgnoreCase)); if (nativeContract != null) contract = NativeContract.ContractManagement.GetContract(NeoSystem.StoreView, nativeContract.Hash); diff --git a/src/Neo.CLI/CLI/MainService.Contracts.cs b/src/Neo.CLI/CLI/MainService.Contracts.cs index b6b703d8f3..1d313aa4f1 100644 --- a/src/Neo.CLI/CLI/MainService.Contracts.cs +++ b/src/Neo.CLI/CLI/MainService.Contracts.cs @@ -101,7 +101,7 @@ private void OnUpdateCommand(UInt160 scriptHash, string filePath, string manifes ConsoleHelper.Error(GetExceptionMessage(e)); return; } - ContractState contract = NativeContract.ContractManagement.GetContract(NeoSystem.StoreView, scriptHash); + ContractState? contract = NativeContract.ContractManagement.GetContract(NeoSystem.StoreView, scriptHash); if (contract == null) { ConsoleHelper.Warning($"Can't upgrade, contract hash not exist: {scriptHash}"); @@ -220,17 +220,17 @@ private void OnInvokeAbiCommand(UInt160 scriptHash, string operation, // Find the method in the ABI with matching parameter count var paramCount = args?.Count ?? 0; var method = contract.Manifest.Abi.GetMethod(operation, paramCount); - if (method == null) + if (method is null) { // Try to find any method with that name for a better error message var anyMethod = contract.Manifest.Abi.GetMethod(operation, -1); - if (anyMethod != null) + if (anyMethod is null) { - ConsoleHelper.Error($"Method '{operation}' exists but expects {anyMethod.Parameters.Length} parameters, not {paramCount}."); + ConsoleHelper.Error($"Method '{operation}' does not exist in this contract."); } else { - ConsoleHelper.Error($"Method '{operation}' does not exist in this contract."); + ConsoleHelper.Error($"Method '{operation}' exists but expects {anyMethod.Parameters.Length} parameters, not {paramCount}."); } return; } diff --git a/src/Neo.CLI/CLI/MainService.NEP17.cs b/src/Neo.CLI/CLI/MainService.NEP17.cs index 2500b7fb76..3413c75fe1 100644 --- a/src/Neo.CLI/CLI/MainService.NEP17.cs +++ b/src/Neo.CLI/CLI/MainService.NEP17.cs @@ -105,7 +105,7 @@ private void OnBalanceOfCommand(UInt160 tokenHash, UInt160 address) [ConsoleCommand("name", Category = "NEP17 Commands")] private void OnNameCommand(UInt160 tokenHash) { - ContractState contract = NativeContract.ContractManagement.GetContract(NeoSystem.StoreView, tokenHash); + ContractState? contract = NativeContract.ContractManagement.GetContract(NeoSystem.StoreView, tokenHash); if (contract == null) Console.WriteLine($"Contract hash not exist: {tokenHash}"); else ConsoleHelper.Info("Result: ", contract.Manifest.Name); } diff --git a/src/Neo.CLI/CLI/MainService.Network.cs b/src/Neo.CLI/CLI/MainService.Network.cs index b7eb7c8bc4..fa503b2f9d 100644 --- a/src/Neo.CLI/CLI/MainService.Network.cs +++ b/src/Neo.CLI/CLI/MainService.Network.cs @@ -54,7 +54,11 @@ private void OnBroadcastAddressCommand(IPAddress payload, ushort port) [ConsoleCommand("broadcast block", Category = "Network Commands")] private void OnBroadcastGetBlocksByHashCommand(UInt256 hash) { - OnBroadcastCommand(MessageCommand.Block, NativeContract.Ledger.GetBlock(NeoSystem.StoreView, hash)); + Block? block = NativeContract.Ledger.GetBlock(NeoSystem.StoreView, hash); + if (block is null) + ConsoleHelper.Error("Block is not found."); + else + OnBroadcastCommand(MessageCommand.Block, block); } /// @@ -64,7 +68,11 @@ private void OnBroadcastGetBlocksByHashCommand(UInt256 hash) [ConsoleCommand("broadcast block", Category = "Network Commands")] private void OnBroadcastGetBlocksByHeightCommand(uint height) { - OnBroadcastCommand(MessageCommand.Block, NativeContract.Ledger.GetBlock(NeoSystem.StoreView, height)); + Block? block = NativeContract.Ledger.GetBlock(NeoSystem.StoreView, height); + if (block is null) + ConsoleHelper.Error("Block is not found."); + else + OnBroadcastCommand(MessageCommand.Block, block); } /// diff --git a/src/Neo.CLI/CLI/MainService.Tools.cs b/src/Neo.CLI/CLI/MainService.Tools.cs index 40a4ae1299..ea093e8d24 100644 --- a/src/Neo.CLI/CLI/MainService.Tools.cs +++ b/src/Neo.CLI/CLI/MainService.Tools.cs @@ -263,7 +263,7 @@ private static string Base64Fixed(string str) { try { - UInt160 scriptHash; + UInt160? scriptHash; if (script.StartsWith("0x")) { if (!UInt160.TryParse(script, out scriptHash)) @@ -273,7 +273,7 @@ private static string Base64Fixed(string str) } else { - if (!UInt160.TryParse(script, out UInt160 littleEndScript)) + if (!UInt160.TryParse(script, out UInt160? littleEndScript)) { return null; } diff --git a/src/Neo.CLI/CLI/MainService.Wallet.cs b/src/Neo.CLI/CLI/MainService.Wallet.cs index 5362f23730..c4eda81819 100644 --- a/src/Neo.CLI/CLI/MainService.Wallet.cs +++ b/src/Neo.CLI/CLI/MainService.Wallet.cs @@ -203,11 +203,11 @@ private void OnExportKeyCommand(string? path = null, UInt160? scriptHash = null) } IEnumerable keys; if (scriptHash == null) - keys = CurrentWallet.GetAccounts().Where(p => p.HasKey).Select(p => p.GetKey()); + keys = CurrentWallet.GetAccounts().Where(p => p.HasKey).Select(p => p.GetKey()!); else { var account = CurrentWallet.GetAccount(scriptHash); - keys = account?.HasKey != true ? Array.Empty() : new[] { account.GetKey() }; + keys = account?.HasKey != true ? Array.Empty() : new[] { account.GetKey()! }; } if (path == null) foreach (KeyPair key in keys) @@ -273,7 +273,7 @@ private void OnImportMultisigAddress(ushort m, ECPoint[] publicKeys) } Contract multiSignContract = Contract.CreateMultiSigContract(m, publicKeys); - KeyPair? keyPair = CurrentWallet!.GetAccounts().FirstOrDefault(p => p.HasKey && publicKeys.Contains(p.GetKey().PublicKey))?.GetKey(); + KeyPair? keyPair = CurrentWallet!.GetAccounts().FirstOrDefault(p => p.HasKey && publicKeys.Contains(p.GetKey()!.PublicKey))?.GetKey(); CurrentWallet.CreateAccount(multiSignContract, keyPair); if (CurrentWallet is NEP6Wallet wallet) @@ -333,7 +333,7 @@ private void OnImportKeyCommand(string wifOrFile) WalletAccount account = CurrentWallet!.CreateAccount(prikey); Array.Clear(prikey, 0, prikey.Length); ConsoleHelper.Info("Address: ", account.Address); - ConsoleHelper.Info(" Pubkey: ", account.GetKey().PublicKey.EncodePoint(true).ToHexString()); + ConsoleHelper.Info(" Pubkey: ", account.GetKey()!.PublicKey.EncodePoint(true).ToHexString()); } if (CurrentWallet is NEP6Wallet wallet) wallet.Save(); @@ -383,7 +383,7 @@ private void OnImportWatchOnlyCommand(string addressOrFile) } else { - WalletAccount account = CurrentWallet!.GetAccount(address); + WalletAccount? account = CurrentWallet!.GetAccount(address); if (account is not null) { ConsoleHelper.Warning("This address is already in your wallet"); @@ -415,7 +415,7 @@ private void OnListAddressCommand() { type = "WatchOnly"; } - else if (IsMultiSigContract(contract.Script)) + else if (IsMultiSigContract(contract!.Script)) { type = "MultiSignature"; } @@ -467,7 +467,7 @@ private void OnListKeyCommand() { ConsoleHelper.Info(" Address: ", account.Address); ConsoleHelper.Info("ScriptHash: ", account.ScriptHash.ToString()); - ConsoleHelper.Info(" PublicKey: ", account.GetKey().PublicKey.EncodePoint(true).ToHexString()); + ConsoleHelper.Info(" PublicKey: ", account.GetKey()!.PublicKey.EncodePoint(true).ToHexString()); Console.WriteLine(); } } @@ -594,7 +594,7 @@ private void OnCancelCommand(UInt256 txid, UInt160? sender = null, UInt160[]? si { if (NoWallet()) return; - TransactionState state = NativeContract.Ledger.GetTransactionState(NeoSystem.StoreView, txid); + TransactionState? state = NativeContract.Ledger.GetTransactionState(NeoSystem.StoreView, txid); if (state != null) { ConsoleHelper.Error("This tx is already confirmed, can't be cancelled."); diff --git a/src/Neo.CLI/CLI/MainService.cs b/src/Neo.CLI/CLI/MainService.cs index 9610c9c94b..5f5d3982fa 100644 --- a/src/Neo.CLI/CLI/MainService.cs +++ b/src/Neo.CLI/CLI/MainService.cs @@ -42,7 +42,7 @@ namespace Neo.CLI { public partial class MainService : ConsoleServiceBase, IWalletProvider { - public event EventHandler? WalletChanged = null; + public event EventHandler? WalletChanged; public const long TestModeGas = 20_00000000; @@ -142,7 +142,7 @@ public override void RunConsole() public void CreateWallet(string path, string password, bool createDefaultAccount = true, string? walletName = null) { - Wallet wallet = Wallet.Create(walletName, path, password, NeoSystem.Settings); + Wallet? wallet = Wallet.Create(walletName, path, password, NeoSystem.Settings); if (wallet == null) { ConsoleHelper.Warning("Wallet files in that format are not supported, please use a .json or .db3 file extension."); @@ -152,7 +152,7 @@ public void CreateWallet(string path, string password, bool createDefaultAccount { WalletAccount account = wallet.CreateAccount(); ConsoleHelper.Info(" Address: ", account.Address); - ConsoleHelper.Info(" Pubkey: ", account.GetKey().PublicKey.EncodePoint(true).ToHexString()); + ConsoleHelper.Info(" Pubkey: ", account.GetKey()!.PublicKey.EncodePoint(true).ToHexString()); ConsoleHelper.Info("ScriptHash: ", $"{account.ScriptHash}"); } wallet.Save(); @@ -503,7 +503,7 @@ private bool OnInvokeWithResult(UInt160 scriptHash, string operation, out StackI } else { - if (contract.Manifest.Abi.GetMethod(operation, parameters.Count) == null) + if (contract.Manifest.Abi.GetMethod(operation, parameters.Count) is null) { ConsoleHelper.Error("This method does not not exist in this contract."); result = StackItem.Null; @@ -539,7 +539,7 @@ private void PrintExecutionOutput(ApplicationEngine engine, bool showStack = tru ConsoleHelper.Info("Result Stack: ", new JArray(engine.ResultStack.Select(p => p.ToJson())).ToString()); if (engine.State == VMState.FAULT) - ConsoleHelper.Error(GetExceptionMessage(engine.FaultException)); + ConsoleHelper.Error(GetExceptionMessage(engine.FaultException!)); } static string GetExceptionMessage(Exception exception) @@ -570,7 +570,7 @@ static string GetExceptionMessage(Exception exception) { try { - var addressData = data.GetString(); + var addressData = data.GetString()!; if (UInt160.TryParse(addressData, out var address)) return address; else diff --git a/src/Neo.CLI/Settings.cs b/src/Neo.CLI/Settings.cs index d66068c65a..5545740979 100644 --- a/src/Neo.CLI/Settings.cs +++ b/src/Neo.CLI/Settings.cs @@ -13,7 +13,6 @@ using Neo.Network.P2P; using Neo.Persistence.Providers; using System; -using System.IO; using System.Reflection; using System.Threading; @@ -47,7 +46,7 @@ public static Settings Default { if (s_default == null) { - var configFile = ProtocolSettings.FindFile("config.json", Environment.CurrentDirectory); + var configFile = ProtocolSettings.FindFile("config.json", Environment.CurrentDirectory)!; var config = new ConfigurationBuilder().AddJsonFile(configFile, optional: true).Build(); Initialize(config); } diff --git a/src/Neo.Cryptography.MPTTrie/Cache.cs b/src/Neo.Cryptography.MPTTrie/Cache.cs index 93fff63bbd..f1eb7885e8 100644 --- a/src/Neo.Cryptography.MPTTrie/Cache.cs +++ b/src/Neo.Cryptography.MPTTrie/Cache.cs @@ -102,7 +102,7 @@ public void Commit() { case TrackState.Added: case TrackState.Changed: - _store.Put(Key(item.Key), item.Value.Node.ToArray()); + _store.Put(Key(item.Key), item.Value.Node!.ToArray()); break; case TrackState.Deleted: _store.Delete(Key(item.Key)); diff --git a/src/Neo.Extensions/Exceptions/TryCatchExtensions.cs b/src/Neo.Extensions/Exceptions/TryCatchExtensions.cs index 123c6cd2bd..81185b994e 100644 --- a/src/Neo.Extensions/Exceptions/TryCatchExtensions.cs +++ b/src/Neo.Extensions/Exceptions/TryCatchExtensions.cs @@ -29,8 +29,8 @@ public static TSource TryCatch(this TSource obj, Action actio return obj; } - public static TSource TryCatch(this TSource obj, Action action, Action? onError = default) - where TSource : class? + public static TSource TryCatch(this TSource obj, Action action, Action? onError = default) + where TSource : notnull where TException : Exception { try @@ -45,10 +45,9 @@ public static TSource TryCatch(this TSource obj, Action(this TSource obj, Func func, Func? onError = default) - where TSource : class? + public static TResult TryCatch(this TSource obj, Func func, Func? onError = default) + where TSource : notnull where TException : Exception - where TResult : class? { try { @@ -56,7 +55,8 @@ public static TSource TryCatch(this TSource obj, Action(this TSource obj, Actio } } - public static TResult? TryCatchThrow(this TSource obj, Func func) - where TSource : class? + public static TResult TryCatchThrow(this TSource obj, Func func) + where TSource : notnull where TException : Exception - where TResult : class? { try { diff --git a/src/Neo.Extensions/SecureStringExtensions.cs b/src/Neo.Extensions/SecureStringExtensions.cs index c895c7f782..ac1d284ee4 100644 --- a/src/Neo.Extensions/SecureStringExtensions.cs +++ b/src/Neo.Extensions/SecureStringExtensions.cs @@ -17,16 +17,14 @@ namespace Neo.Extensions { public static class SecureStringExtensions { - public static string? GetClearText(this SecureString secureString) + public static string GetClearText(this SecureString secureString) { - ArgumentNullException.ThrowIfNull(secureString); - var unmanagedStringPtr = IntPtr.Zero; try { unmanagedStringPtr = Marshal.SecureStringToGlobalAllocUnicode(secureString); - return Marshal.PtrToStringUni(unmanagedStringPtr); + return Marshal.PtrToStringUni(unmanagedStringPtr)!; } finally { diff --git a/src/Neo.Json/JString.cs b/src/Neo.Json/JString.cs index 0dbf354ec4..f6b507a402 100644 --- a/src/Neo.Json/JString.cs +++ b/src/Neo.Json/JString.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Text.Json; @@ -89,18 +90,20 @@ public static implicit operator JString(Enum value) return new JString(value.ToString()); } + [return: NotNullIfNotNull(nameof(value))] public static implicit operator JString?(string? value) { - return value == null ? null : new JString(value); + return value is null ? null : new JString(value); } - public static bool operator ==(JString left, JString? right) + public static bool operator ==(JString? left, JString? right) { - if (right is null) return false; - return ReferenceEquals(left, right) || left.Value.Equals(right.Value); + if (ReferenceEquals(left, right)) return true; + if (left is null || right is null) return false; + return left.Value.Equals(right.Value); } - public static bool operator !=(JString left, JString right) + public static bool operator !=(JString? left, JString? right) { return !(left == right); } diff --git a/src/Neo/BigDecimal.cs b/src/Neo/BigDecimal.cs index 204b792d12..f438e3d7f1 100644 --- a/src/Neo/BigDecimal.cs +++ b/src/Neo/BigDecimal.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - using System; using System.Numerics; using System.Runtime.InteropServices; @@ -241,5 +239,3 @@ public override readonly int GetHashCode() } } } - -#nullable disable diff --git a/src/Neo/Builders/SignerBuilder.cs b/src/Neo/Builders/SignerBuilder.cs index afd768d13a..0e0a2cdd8d 100644 --- a/src/Neo/Builders/SignerBuilder.cs +++ b/src/Neo/Builders/SignerBuilder.cs @@ -12,48 +12,43 @@ using Neo.Cryptography.ECC; using Neo.Network.P2P.Payloads; using System; +using System.Collections.Generic; namespace Neo.Builders { public sealed class SignerBuilder { - private readonly Signer _signer = new Signer() - { - Account = UInt160.Zero, - AllowedContracts = [], - AllowedGroups = [], - Rules = [], - Scopes = WitnessScope.None, - }; - - private SignerBuilder() { } + private readonly UInt160 _account; + private WitnessScope _scopes = WitnessScope.None; + private readonly List _allowedContracts = []; + private readonly List _allowedGroups = []; + private readonly List _rules = []; - public static SignerBuilder CreateEmpty() + private SignerBuilder(UInt160 account) { - return new SignerBuilder(); + _account = account; } - public SignerBuilder Account(UInt160 scriptHash) + public static SignerBuilder Create(UInt160 account) { - _signer.Account = scriptHash; - return this; + return new SignerBuilder(account); } public SignerBuilder AllowContract(UInt160 contractHash) { - _signer.AllowedContracts = [.. _signer.AllowedContracts, contractHash]; - return this; + _allowedContracts.Add(contractHash); + return AddWitnessScope(WitnessScope.CustomContracts); } public SignerBuilder AllowGroup(ECPoint publicKey) { - _signer.AllowedGroups = [.. _signer.AllowedGroups, publicKey]; - return this; + _allowedGroups.Add(publicKey); + return AddWitnessScope(WitnessScope.CustomGroups); } public SignerBuilder AddWitnessScope(WitnessScope scope) { - _signer.Scopes |= scope; + _scopes |= scope; return this; } @@ -61,13 +56,20 @@ public SignerBuilder AddWitnessRule(WitnessRuleAction action, Action config) + public TransactionAttributesBuilder AddConflict(UInt256 hash) { - var conflicts = new Conflicts(); - config(conflicts); + var conflicts = new Conflicts { Hash = hash }; _attributes = [.. _attributes, conflicts]; return this; } diff --git a/src/Neo/Builders/TransactionBuilder.cs b/src/Neo/Builders/TransactionBuilder.cs index 6e0e651162..ec69c6d64f 100644 --- a/src/Neo/Builders/TransactionBuilder.cs +++ b/src/Neo/Builders/TransactionBuilder.cs @@ -100,9 +100,9 @@ public TransactionBuilder AddWitness(Action config) return this; } - public TransactionBuilder AddSigner(Action config) + public TransactionBuilder AddSigner(UInt160 account, Action config) { - var wb = SignerBuilder.CreateEmpty(); + var wb = SignerBuilder.Create(account); config(wb, _tx); _tx.Signers = [.. _tx.Signers, wb.Build()]; return this; diff --git a/src/Neo/Builders/WitnessConditionBuilder.cs b/src/Neo/Builders/WitnessConditionBuilder.cs index 5f88da065c..f42e918c11 100644 --- a/src/Neo/Builders/WitnessConditionBuilder.cs +++ b/src/Neo/Builders/WitnessConditionBuilder.cs @@ -17,15 +17,10 @@ namespace Neo.Builders { public sealed class WitnessConditionBuilder { - WitnessCondition _condition; + WitnessCondition? _condition; private WitnessConditionBuilder() { } - private WitnessConditionBuilder(WitnessCondition condition) - { - _condition = condition; - } - public static WitnessConditionBuilder Create() { return new WitnessConditionBuilder(); diff --git a/src/Neo/Builders/WitnessRuleBuilder.cs b/src/Neo/Builders/WitnessRuleBuilder.cs index 943144800e..082c94919d 100644 --- a/src/Neo/Builders/WitnessRuleBuilder.cs +++ b/src/Neo/Builders/WitnessRuleBuilder.cs @@ -10,17 +10,19 @@ // modifications are permitted. using Neo.Network.P2P.Payloads; +using Neo.Network.P2P.Payloads.Conditions; using System; namespace Neo.Builders { public sealed class WitnessRuleBuilder { - private readonly WitnessRule _rule = new(); + private readonly WitnessRuleAction _action; + private WitnessCondition? _condition; private WitnessRuleBuilder(WitnessRuleAction action) { - _rule.Action = action; + _action = action; } public static WitnessRuleBuilder Create(WitnessRuleAction action) @@ -32,13 +34,17 @@ public WitnessRuleBuilder AddCondition(Action config) { var cb = WitnessConditionBuilder.Create(); config(cb); - _rule.Condition = cb.Build(); + _condition = cb.Build(); return this; } public WitnessRule Build() { - return _rule; + return new() + { + Action = _action, + Condition = _condition ?? throw new InvalidOperationException("Condition is not set."), + }; } } } diff --git a/src/Neo/Cryptography/BloomFilter.cs b/src/Neo/Cryptography/BloomFilter.cs index 4408bc95d0..14894ce9b5 100644 --- a/src/Neo/Cryptography/BloomFilter.cs +++ b/src/Neo/Cryptography/BloomFilter.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - using System; using System.Collections; using System.Linq; @@ -114,5 +112,3 @@ public void GetBits(byte[] newBits) } } } - -#nullable disable diff --git a/src/Neo/Cryptography/Crypto.cs b/src/Neo/Cryptography/Crypto.cs index 0a975cb044..bda17f73cd 100644 --- a/src/Neo/Cryptography/Crypto.cs +++ b/src/Neo/Cryptography/Crypto.cs @@ -77,8 +77,9 @@ public static byte[] Sign(byte[] message, byte[] priKey, ECC.ECCurve ecCurve, Ha /// The curve of the signature, default is . /// The hash algorithm to hash the message, default is SHA256. /// The ECDSA signature for the specified message. - public static byte[] Sign(byte[] message, byte[] priKey, ECC.ECCurve ecCurve = null, HashAlgorithm hashAlgorithm = HashAlgorithm.SHA256) + public static byte[] Sign(byte[] message, byte[] priKey, ECC.ECCurve? ecCurve = null, HashAlgorithm hashAlgorithm = HashAlgorithm.SHA256) { + ecCurve ??= ECC.ECCurve.Secp256r1; if (hashAlgorithm == HashAlgorithm.Keccak256 || (s_isOSX && ecCurve == ECC.ECCurve.Secp256k1)) { var signer = new ECDsaSigner(); @@ -99,7 +100,7 @@ public static byte[] Sign(byte[] message, byte[] priKey, ECC.ECCurve ecCurve = n } var curve = - ecCurve == null || ecCurve == ECC.ECCurve.Secp256r1 ? ECCurve.NamedCurves.nistP256 : + ecCurve == ECC.ECCurve.Secp256r1 ? ECCurve.NamedCurves.nistP256 : ecCurve == ECC.ECCurve.Secp256k1 ? s_secP256k1 : throw new NotSupportedException($"The elliptic curve {ecCurve} is not supported. Only Secp256r1 and Secp256k1 curves are supported for ECDSA signing operations."); @@ -143,8 +144,8 @@ public static bool VerifySignature(ReadOnlySpan message, ReadOnlySpan, IEquatable, ISerializable, ISerializableSpan { internal ECFieldElement? X, Y; - internal readonly ECCurve Curve; + internal ECCurve Curve { get => field ?? ECCurve.Secp256r1; private init; } private byte[]? _compressedPoint, _uncompressedPoint; /// @@ -473,5 +471,3 @@ private static sbyte[] WindowNaf(sbyte width, BigInteger k) } } } - -#nullable disable diff --git a/src/Neo/Cryptography/Helper.cs b/src/Neo/Cryptography/Helper.cs index e7cf61e107..5c77a8ac87 100644 --- a/src/Neo/Cryptography/Helper.cs +++ b/src/Neo/Cryptography/Helper.cs @@ -226,7 +226,7 @@ public static byte[] Keccak256(this ReadOnlySpan value) /// The computed hash code. public static byte[] Keccak256(this Span value) => ((ReadOnlySpan)value).Keccak256(); - public static byte[] AES256Encrypt(this byte[] plainData, byte[] key, byte[] nonce, byte[] associatedData = null) + public static byte[] AES256Encrypt(this byte[] plainData, byte[] key, byte[] nonce, byte[]? associatedData = null) { if (nonce.Length != AesNonceSizeBytes) throw new ArgumentOutOfRangeException(nameof(nonce), $"`nonce` must be {AesNonceSizeBytes} bytes"); @@ -254,7 +254,7 @@ public static byte[] AES256Encrypt(this byte[] plainData, byte[] key, byte[] non return [.. nonce, .. cipherBytes, .. tag]; } - public static byte[] AES256Decrypt(this byte[] encryptedData, byte[] key, byte[] associatedData = null) + public static byte[] AES256Decrypt(this byte[] encryptedData, byte[] key, byte[]? associatedData = null) { if (encryptedData.Length < AesNonceSizeBytes + AesTagSizeBytes) throw new ArgumentException($"The encryptedData.Length must be greater than {AesNonceSizeBytes} + {AesTagSizeBytes}"); diff --git a/src/Neo/Cryptography/MerkleTree.cs b/src/Neo/Cryptography/MerkleTree.cs index 701d39fe8d..f0c9cd58b9 100644 --- a/src/Neo/Cryptography/MerkleTree.cs +++ b/src/Neo/Cryptography/MerkleTree.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - using Neo.Extensions; using System; using System.Collections; @@ -66,7 +64,7 @@ internal MerkleTree(UInt256[] hashes) parents[i].RightChild = leaves[i * 2 + 1]; leaves[i * 2 + 1].Parent = parents[i]; } - parents[i].Hash = Concat(buffer, parents[i].LeftChild.Hash, parents[i].RightChild.Hash); + parents[i].Hash = Concat(buffer, parents[i].LeftChild!.Hash!, parents[i].RightChild!.Hash!); } return Build(parents); //TailCall } @@ -91,7 +89,7 @@ public static UInt256 ComputeRoot(UInt256[] hashes) if (hashes.Length == 1) return hashes[0]; var tree = new MerkleTree(hashes); - return tree._root!.Hash; + return tree._root!.Hash!; } private static void DepthFirstSearch(MerkleTreeNode node, List hashes) @@ -99,12 +97,12 @@ private static void DepthFirstSearch(MerkleTreeNode node, List hashes) if (node.LeftChild == null) { // if left is null, then right must be null - hashes.Add(node.Hash); + hashes.Add(node.Hash!); } else { DepthFirstSearch(node.LeftChild, hashes); - DepthFirstSearch(node.RightChild, hashes); + DepthFirstSearch(node.RightChild!, hashes); } } @@ -149,8 +147,8 @@ private static void Trim(MerkleTreeNode node, int index, int depth, BitArray fla else { Trim(node.LeftChild, index * 2, depth - 1, flags); - Trim(node.RightChild, index * 2 + 1, depth - 1, flags); - if (node.LeftChild.LeftChild == null && node.RightChild.RightChild == null) + Trim(node.RightChild!, index * 2 + 1, depth - 1, flags); + if (node.LeftChild.LeftChild == null && node.RightChild!.RightChild == null) { node.LeftChild = null; node.RightChild = null; @@ -159,5 +157,3 @@ private static void Trim(MerkleTreeNode node, int index, int depth, BitArray fla } } } - -#nullable disable diff --git a/src/Neo/Cryptography/MerkleTreeNode.cs b/src/Neo/Cryptography/MerkleTreeNode.cs index 11fceedab7..58dc47cbd3 100644 --- a/src/Neo/Cryptography/MerkleTreeNode.cs +++ b/src/Neo/Cryptography/MerkleTreeNode.cs @@ -11,12 +11,12 @@ namespace Neo.Cryptography { - internal class MerkleTreeNode + class MerkleTreeNode { - public UInt256 Hash { get; set; } - public MerkleTreeNode Parent { get; set; } - public MerkleTreeNode LeftChild { get; set; } - public MerkleTreeNode RightChild { get; set; } + public UInt256? Hash { get; set; } + public MerkleTreeNode? Parent { get; set; } + public MerkleTreeNode? LeftChild { get; set; } + public MerkleTreeNode? RightChild { get; set; } public bool IsLeaf => LeftChild == null && RightChild == null; public bool IsRoot => Parent == null; diff --git a/src/Neo/Extensions/ByteExtensions.cs b/src/Neo/Extensions/ByteExtensions.cs index 5aa7c8bbc9..cb4303fc53 100644 --- a/src/Neo/Extensions/ByteExtensions.cs +++ b/src/Neo/Extensions/ByteExtensions.cs @@ -44,7 +44,7 @@ public static byte[] DecompressLz4(this byte[] data, int maxOutput) /// The byte array to be converted. /// The offset into the byte array from which to begin using data. /// The converted object. - public static T AsSerializable(this byte[] value, int start = 0) where T : ISerializable, new() + public static T AsSerializable(this byte[] value, int start = 0) where T : ISerializable { MemoryReader reader = new(value.AsMemory(start)); return reader.ReadSerializable(); @@ -57,7 +57,7 @@ public static byte[] DecompressLz4(this byte[] data, int maxOutput) /// The byte array to be converted. /// The maximum number of elements contained in the converted array. /// The converted array. - public static T[] AsSerializableArray(this byte[] value, int max = 0x1000000) where T : ISerializable, new() + public static T[] AsSerializableArray(this byte[] value, int max = 0x1000000) where T : ISerializable { MemoryReader reader = new(value); return reader.ReadSerializableArray(max); diff --git a/src/Neo/Extensions/IO/BinaryWriterExtensions.cs b/src/Neo/Extensions/IO/BinaryWriterExtensions.cs index 3dfd2ebf00..b1d388c8b5 100644 --- a/src/Neo/Extensions/IO/BinaryWriterExtensions.cs +++ b/src/Neo/Extensions/IO/BinaryWriterExtensions.cs @@ -14,8 +14,6 @@ using System.Collections.Generic; using System.IO; -#nullable enable - namespace Neo.Extensions { public static class BinaryWriterExtensions @@ -141,5 +139,3 @@ public static void WriteVarString(this BinaryWriter writer, string value) } } } - -#nullable disable diff --git a/src/Neo/Extensions/IO/MemoryReaderExtensions.cs b/src/Neo/Extensions/IO/MemoryReaderExtensions.cs index edb49ae659..47cac82565 100644 --- a/src/Neo/Extensions/IO/MemoryReaderExtensions.cs +++ b/src/Neo/Extensions/IO/MemoryReaderExtensions.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Neo.IO; +using System.Runtime.CompilerServices; namespace Neo.Extensions { @@ -25,10 +26,10 @@ public static class MemoryReaderExtensions /// The for reading data. /// The maximum number of elements in the array. /// The array read from the . - public static T[] ReadNullableArray(this ref MemoryReader reader, int max = 0x1000000) - where T : class, ISerializable, new() + public static T?[] ReadNullableArray(this ref MemoryReader reader, int max = 0x1000000) + where T : class, ISerializable { - var array = new T[reader.ReadVarInt((ulong)max)]; + var array = new T?[reader.ReadVarInt((ulong)max)]; for (var i = 0; i < array.Length; i++) array[i] = reader.ReadBoolean() ? reader.ReadSerializable() : null; return array; @@ -41,9 +42,9 @@ public static T[] ReadNullableArray(this ref MemoryReader reader, int max = 0 /// The for reading data. /// The object read from the . public static T ReadSerializable(this ref MemoryReader reader) - where T : ISerializable, new() + where T : ISerializable { - T obj = new(); + T obj = (T)RuntimeHelpers.GetUninitializedObject(typeof(T)); obj.Deserialize(ref reader); return obj; } @@ -56,12 +57,12 @@ public static T ReadSerializable(this ref MemoryReader reader) /// The maximum number of elements in the array. /// The array read from the . public static T[] ReadSerializableArray(this ref MemoryReader reader, int max = 0x1000000) - where T : ISerializable, new() + where T : ISerializable { var array = new T[reader.ReadVarInt((ulong)max)]; for (var i = 0; i < array.Length; i++) { - array[i] = new T(); + array[i] = (T)RuntimeHelpers.GetUninitializedObject(typeof(T)); array[i].Deserialize(ref reader); } return array; diff --git a/src/Neo/Extensions/MemoryExtensions.cs b/src/Neo/Extensions/MemoryExtensions.cs index 096d9bd441..f528be9ca3 100644 --- a/src/Neo/Extensions/MemoryExtensions.cs +++ b/src/Neo/Extensions/MemoryExtensions.cs @@ -38,7 +38,7 @@ public static class MemoryExtensions /// The byte array to be converted. /// The converted object. public static T AsSerializable(this ReadOnlyMemory value) - where T : ISerializable, new() + where T : ISerializable { if (value.IsEmpty) throw new FormatException("`value` is empty"); MemoryReader reader = new(value); @@ -55,7 +55,7 @@ public static ISerializable AsSerializable(this ReadOnlyMemory value, Type { if (!typeof(ISerializable).GetTypeInfo().IsAssignableFrom(type)) throw new InvalidCastException($"`{type.Name}` is not assignable from `ISerializable`"); - var serializable = (ISerializable)Activator.CreateInstance(type); + var serializable = (ISerializable)Activator.CreateInstance(type)!; MemoryReader reader = new(value); serializable.Deserialize(ref reader); return serializable; diff --git a/src/Neo/Extensions/SmartContract/ContractParameterExtensions.cs b/src/Neo/Extensions/SmartContract/ContractParameterExtensions.cs index 1998156c84..0eb315fb93 100644 --- a/src/Neo/Extensions/SmartContract/ContractParameterExtensions.cs +++ b/src/Neo/Extensions/SmartContract/ContractParameterExtensions.cs @@ -32,11 +32,11 @@ public static StackItem ToStackItem(this ContractParameter parameter) return ToStackItem(parameter, null); } - private static StackItem ToStackItem(ContractParameter parameter, List<(StackItem, ContractParameter)> context) + private static StackItem ToStackItem(ContractParameter parameter, List<(StackItem, ContractParameter)>? context) { ArgumentNullException.ThrowIfNull(parameter); if (parameter.Value is null) return StackItem.Null; - StackItem stackItem = null; + StackItem? stackItem = null; switch (parameter.Type) { case ContractParameterType.Array: diff --git a/src/Neo/Extensions/SmartContract/ContractStateExtensions.cs b/src/Neo/Extensions/SmartContract/ContractStateExtensions.cs index 7874d71f18..6ef956dab0 100644 --- a/src/Neo/Extensions/SmartContract/ContractStateExtensions.cs +++ b/src/Neo/Extensions/SmartContract/ContractStateExtensions.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - using Neo.Persistence; using Neo.SmartContract; using Neo.SmartContract.Native; @@ -88,5 +86,3 @@ public static class ContractStateExtensions } } } - -#nullable disable diff --git a/src/Neo/Extensions/UInt160Extensions.cs b/src/Neo/Extensions/UInt160Extensions.cs index e82276ef66..38952e862b 100644 --- a/src/Neo/Extensions/UInt160Extensions.cs +++ b/src/Neo/Extensions/UInt160Extensions.cs @@ -22,7 +22,7 @@ public static class UInt160Extensions /// The method to be called in the contract. /// The arguments for calling the contract. /// The generated script. - public static byte[] MakeScript(this UInt160 scriptHash, string method, params object[] args) + public static byte[] MakeScript(this UInt160 scriptHash, string method, params object?[] args) { using ScriptBuilder sb = new(); sb.EmitDynamicCall(scriptHash, method, args); diff --git a/src/Neo/Extensions/VM/ScriptBuilderExtensions.cs b/src/Neo/Extensions/VM/ScriptBuilderExtensions.cs index ad8aed96d1..49ca3f5100 100644 --- a/src/Neo/Extensions/VM/ScriptBuilderExtensions.cs +++ b/src/Neo/Extensions/VM/ScriptBuilderExtensions.cs @@ -29,7 +29,7 @@ public static class ScriptBuilderExtensions /// The to be used. /// The elements of the array. /// The same instance as . - public static ScriptBuilder CreateArray(this ScriptBuilder builder, IReadOnlyList list = null) + public static ScriptBuilder CreateArray(this ScriptBuilder builder, IReadOnlyList? list = null) { if (list is null || list.Count == 0) return builder.Emit(OpCode.NEWARRAY0); @@ -128,7 +128,7 @@ public static ScriptBuilder Emit(this ScriptBuilder builder, params OpCode[] ops /// The method to be called in the contract. /// The arguments for calling the contract. /// The same instance as . - public static ScriptBuilder EmitDynamicCall(this ScriptBuilder builder, UInt160 scriptHash, string method, params object[] args) + public static ScriptBuilder EmitDynamicCall(this ScriptBuilder builder, UInt160 scriptHash, string method, params object?[] args) { return EmitDynamicCall(builder, scriptHash, method, CallFlags.All, args); } @@ -142,7 +142,7 @@ public static ScriptBuilder EmitDynamicCall(this ScriptBuilder builder, UInt160 /// The for calling the contract. /// The arguments for calling the contract. /// The same instance as . - public static ScriptBuilder EmitDynamicCall(this ScriptBuilder builder, UInt160 scriptHash, string method, CallFlags flags, params object[] args) + public static ScriptBuilder EmitDynamicCall(this ScriptBuilder builder, UInt160 scriptHash, string method, CallFlags flags, params object?[] args) { builder.CreateArray(args); builder.EmitPush(flags); @@ -187,7 +187,7 @@ public static ScriptBuilder EmitPush(this ScriptBuilder builder, ContractParamet if (parameter.Value is BigInteger bi) builder.EmitPush(bi); else - builder.EmitPush((BigInteger)typeof(BigInteger).GetConstructor([parameter.Value.GetType()]).Invoke([parameter.Value])); + builder.EmitPush((BigInteger)typeof(BigInteger).GetConstructor([parameter.Value.GetType()])!.Invoke([parameter.Value])); break; case ContractParameterType.Hash160: builder.EmitPush((UInt160)parameter.Value); @@ -228,7 +228,7 @@ public static ScriptBuilder EmitPush(this ScriptBuilder builder, ContractParamet /// The to be used. /// The data to be pushed. /// The same instance as . - public static ScriptBuilder EmitPush(this ScriptBuilder builder, object obj) + public static ScriptBuilder EmitPush(this ScriptBuilder builder, object? obj) { switch (obj) { diff --git a/src/Neo/Extensions/VM/StackItemExtensions.cs b/src/Neo/Extensions/VM/StackItemExtensions.cs index b1be48f238..07e7f1afcb 100644 --- a/src/Neo/Extensions/VM/StackItemExtensions.cs +++ b/src/Neo/Extensions/VM/StackItemExtensions.cs @@ -11,7 +11,6 @@ using Neo.Json; using Neo.SmartContract; -using Neo.VM; using Neo.VM.Types; using System; using System.Collections.Generic; @@ -35,13 +34,13 @@ public static JObject ToJson(this StackItem item, int maxSize = int.MaxValue) return ToJson(item, null, ref maxSize); } - public static JObject ToJson(this StackItem item, HashSet context, ref int maxSize) + public static JObject ToJson(this StackItem item, HashSet? context, ref int maxSize) { JObject json = new() { ["type"] = item.Type }; - JToken value = null; + JToken? value = null; maxSize -= 11/*{"type":""}*/+ item.Type.ToString().Length; switch (item) { @@ -125,10 +124,10 @@ public static ContractParameter ToParameter(this StackItem item) return ToParameter(item, null); } - public static ContractParameter ToParameter(this StackItem item, List<(StackItem, ContractParameter)> context) + public static ContractParameter ToParameter(this StackItem item, List<(StackItem, ContractParameter)>? context) { ArgumentNullException.ThrowIfNull(item); - ContractParameter parameter = null; + ContractParameter? parameter = null; switch (item) { case Array array: diff --git a/src/Neo/IO/Actors/PriorityMailbox.cs b/src/Neo/IO/Actors/PriorityMailbox.cs index 8628844785..def7d30bd2 100644 --- a/src/Neo/IO/Actors/PriorityMailbox.cs +++ b/src/Neo/IO/Actors/PriorityMailbox.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - using Akka.Actor; using Akka.Configuration; using Akka.Dispatch; @@ -29,5 +27,3 @@ public override IMessageQueue Create(IActorRef owner, ActorSystem system) => internal protected virtual bool ShallDrop(object message, IEnumerable queue) => false; } } - -#nullable disable diff --git a/src/Neo/IO/Actors/PriorityMessageQueue.cs b/src/Neo/IO/Actors/PriorityMessageQueue.cs index 7cd2630f71..a6c3be3324 100644 --- a/src/Neo/IO/Actors/PriorityMessageQueue.cs +++ b/src/Neo/IO/Actors/PriorityMessageQueue.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - using Akka.Actor; using Akka.Dispatch; using Akka.Dispatch.MessageQueues; @@ -61,5 +59,3 @@ public bool TryDequeue(out Envelope envelope) } } } - -#nullable disable diff --git a/src/Neo/IO/Caching/ECDsaCache.cs b/src/Neo/IO/Caching/ECDsaCache.cs index 021d8b351d..5f7451950a 100644 --- a/src/Neo/IO/Caching/ECDsaCache.cs +++ b/src/Neo/IO/Caching/ECDsaCache.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - using System.Collections.Generic; using System.Security.Cryptography; using ECPoint = Neo.Cryptography.ECC.ECPoint; @@ -30,5 +28,3 @@ protected override ECPoint GetKeyForItem(ECDsaCacheItem item) } } } - -#nullable disable diff --git a/src/Neo/IO/Caching/ECPointCache.cs b/src/Neo/IO/Caching/ECPointCache.cs index 79494d8b27..9b899a1157 100644 --- a/src/Neo/IO/Caching/ECPointCache.cs +++ b/src/Neo/IO/Caching/ECPointCache.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - using Neo.Cryptography.ECC; using Neo.Extensions; @@ -27,5 +25,3 @@ protected override byte[] GetKeyForItem(ECPoint item) } } } - -#nullable disable diff --git a/src/Neo/IO/Caching/ReflectionCache.cs b/src/Neo/IO/Caching/ReflectionCache.cs index 796f2cc678..2f1aaad0d3 100644 --- a/src/Neo/IO/Caching/ReflectionCache.cs +++ b/src/Neo/IO/Caching/ReflectionCache.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - using Neo.Extensions; using System; using System.Collections.Generic; @@ -59,5 +57,3 @@ static ReflectionCache() } } } - -#nullable disable diff --git a/src/Neo/IO/Caching/RelayCache.cs b/src/Neo/IO/Caching/RelayCache.cs index 28ac7c2bf8..2a5412b1b5 100644 --- a/src/Neo/IO/Caching/RelayCache.cs +++ b/src/Neo/IO/Caching/RelayCache.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - using Neo.Network.P2P.Payloads; namespace Neo.IO.Caching @@ -23,5 +21,3 @@ protected override UInt256 GetKeyForItem(IInventory item) } } } - -#nullable disable diff --git a/src/Neo/Ledger/Blockchain.ApplicationExecuted.cs b/src/Neo/Ledger/Blockchain.ApplicationExecuted.cs index a48e9a397d..a2f9144cd8 100644 --- a/src/Neo/Ledger/Blockchain.ApplicationExecuted.cs +++ b/src/Neo/Ledger/Blockchain.ApplicationExecuted.cs @@ -24,7 +24,7 @@ partial class ApplicationExecuted /// /// The transaction that contains the executed script. This field could be if the contract is invoked by system. /// - public Transaction Transaction { get; } + public Transaction? Transaction { get; } /// /// The trigger of the execution. @@ -39,7 +39,7 @@ partial class ApplicationExecuted /// /// The exception that caused the execution to terminate abnormally. This field could be if the execution ends normally. /// - public Exception Exception { get; } + public Exception? Exception { get; } /// /// GAS spent to execute. diff --git a/src/Neo/Ledger/Blockchain.cs b/src/Neo/Ledger/Blockchain.cs index c12186d646..0b0fb4cab6 100644 --- a/src/Neo/Ledger/Blockchain.cs +++ b/src/Neo/Ledger/Blockchain.cs @@ -45,93 +45,61 @@ public partial class ApplicationExecuted { } /// /// Sent by the when a is persisted. /// - public class PersistCompleted - { - /// - /// The that is persisted. - /// - public Block Block { get; init; } - } + /// The that is persisted. + public record PersistCompleted(Block Block); /// /// Sent to the when importing blocks. /// - public class Import - { - /// - /// The blocks to be imported. - /// - public IEnumerable Blocks { get; init; } - - /// - /// Indicates whether the blocks need to be verified when importing. - /// - public bool Verify { get; init; } = true; - } + /// The blocks to be imported. + /// Indicates whether the blocks need to be verified when importing. + public record Import(IEnumerable Blocks, bool Verify = true); /// /// Sent by the when the import is complete. /// - public class ImportCompleted { } + public record ImportCompleted; /// /// Sent to the when the consensus is filling the memory pool. /// - public class FillMemoryPool - { - /// - /// The transactions to be sent. - /// - public IEnumerable Transactions { get; init; } - } + /// The transactions to be sent. + public record FillMemoryPool(IEnumerable Transactions); /// /// Sent by the when the memory pool is filled. /// - public class FillCompleted { } + public record FillCompleted; /// /// Sent to the when inventories need to be re-verified. /// - public class Reverify - { - /// - /// The inventories to be re-verified. - /// - public IReadOnlyList Inventories { get; init; } - } + /// The inventories to be re-verified. + public record Reverify(IReadOnlyList Inventories); /// /// Sent by the when an is relayed. /// - public class RelayResult - { - /// - /// The that is relayed. - /// - public IInventory Inventory { get; init; } - /// - /// The result. - /// - public VerifyResult Result { get; init; } - } + /// The that is relayed. + /// The result. + public record RelayResult(IInventory Inventory, VerifyResult Result); - internal class Initialize { } + internal record Initialize; private class UnverifiedBlocksList { public List Blocks { get; } = []; public HashSet Nodes { get; } = []; } - public static event CommittingHandler Committing; - public static event CommittedHandler Committed; + public static event CommittingHandler? Committing; + public static event CommittedHandler? Committed; private static readonly Script s_onPersistScript, s_postPersistScript; private const int MaxTxToReverifyPerIdle = 10; private readonly NeoSystem _system; private readonly Dictionary _blockCache = []; private readonly Dictionary _blockCacheUnverified = []; - private ImmutableHashSet _extensibleWitnessWhiteList; + private ImmutableHashSet? _extensibleWitnessWhiteList; static Blockchain() { @@ -244,7 +212,7 @@ private void OnInventory(IInventory inventory, bool relay = true) }; if (result == VerifyResult.Succeed && relay) { - _system.LocalNode.Tell(new LocalNode.RelayDirectly { Inventory = inventory }); + _system.LocalNode.Tell(new LocalNode.RelayDirectly(inventory)); } SendRelayResult(inventory, result); } @@ -303,7 +271,7 @@ private VerifyResult OnNewBlock(Block block) // Increase in the rate of 1 block per second in configurations with faster blocks if (blockToPersist.Index + 99 >= headerHeight) - _system.LocalNode.Tell(new LocalNode.RelayDirectly { Inventory = blockToPersist }); + _system.LocalNode.Tell(new LocalNode.RelayDirectly(blockToPersist)); } if (_blockCacheUnverified.TryGetValue(currentHeight + 1, out var unverifiedBlocks)) { @@ -315,7 +283,7 @@ private VerifyResult OnNewBlock(Block block) else { if (block.Index + 99 >= headerHeight) - _system.LocalNode.Tell(new LocalNode.RelayDirectly { Inventory = block }); + _system.LocalNode.Tell(new LocalNode.RelayDirectly(block)); if (block.Index == headerHeight + 1) _system.HeaderCache.Add(block.Header); } @@ -459,14 +427,14 @@ private void Persist(Block block) Context.System.EventStream.Publish(applicationExecuted); allApplicationExecuted.Add(applicationExecuted); - transactionStates = engine.GetState(); + transactionStates = engine.GetState()!; } var clonedSnapshot = snapshot.CloneCache(); // Warning: Do not write into variable snapshot directly. Write into variable clonedSnapshot and commit instead. foreach (var transactionState in transactionStates) { - var tx = transactionState.Transaction; + var tx = transactionState.Transaction!; using var engine = ApplicationEngine.Create(TriggerType.Application, tx, clonedSnapshot, block, _system.Settings, tx.SystemFee); engine.LoadScript(tx.Script); transactionState.State = engine.Execute(); @@ -507,7 +475,7 @@ private void Persist(Block block) _system.MemPool.UpdatePoolForBlockPersisted(block, _system.StoreView); _extensibleWitnessWhiteList = null; _blockCache.Remove(block.PrevHash); - Context.System.EventStream.Publish(new PersistCompleted { Block = block }); + Context.System.EventStream.Publish(new PersistCompleted(block)); if (_system.HeaderCache.TryRemoveFirst(out var header)) Debug.Assert(header.Index == block.Index); } @@ -524,7 +492,7 @@ internal static void InvokeCommitted(NeoSystem system, Block block) InvokeHandlers(Committed?.GetInvocationList(), h => ((CommittedHandler)h)(system, block)); } - private static void InvokeHandlers(Delegate[] handlers, Action handlerAction) + private static void InvokeHandlers(Delegate[]? handlers, Action handlerAction) { if (handlers == null) return; @@ -574,11 +542,7 @@ public static Props Props(NeoSystem system) private void SendRelayResult(IInventory inventory, VerifyResult result) { - RelayResult rr = new() - { - Inventory = inventory, - Result = result - }; + RelayResult rr = new(inventory, result); Sender.Tell(rr); Context.System.EventStream.Publish(rr); } diff --git a/src/Neo/Ledger/HeaderCache.cs b/src/Neo/Ledger/HeaderCache.cs index 1e8662b872..9aebf8e586 100644 --- a/src/Neo/Ledger/HeaderCache.cs +++ b/src/Neo/Ledger/HeaderCache.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - using Neo.IO.Caching; using Neo.Network.P2P.Payloads; using System; @@ -154,5 +152,3 @@ public IEnumerator
GetEnumerator() IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } } - -#nullable disable diff --git a/src/Neo/Ledger/MemoryPool.cs b/src/Neo/Ledger/MemoryPool.cs index 61a280c988..35748ef018 100644 --- a/src/Neo/Ledger/MemoryPool.cs +++ b/src/Neo/Ledger/MemoryPool.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - using Neo.Network.P2P; using Neo.Network.P2P.Payloads; using Neo.Persistence; @@ -626,7 +624,7 @@ private int ReverifyTransactions(int count, double millisecondsTimeout, DataCach { if (item.LastBroadcastTimestamp < rebroadcastCutOffTime) { - _system.LocalNode.Tell(new LocalNode.RelayDirectly { Inventory = item.Tx }, _system.Blockchain); + _system.LocalNode.Tell(new LocalNode.RelayDirectly(item.Tx), _system.Blockchain); item.LastBroadcastTimestamp = TimeProvider.Current.UtcNow; } } @@ -701,5 +699,3 @@ internal void Clear() } } } - -#nullable disable diff --git a/src/Neo/Ledger/PoolItem.cs b/src/Neo/Ledger/PoolItem.cs index 57934f1c41..664dea8206 100644 --- a/src/Neo/Ledger/PoolItem.cs +++ b/src/Neo/Ledger/PoolItem.cs @@ -59,7 +59,7 @@ public int CompareTo(Transaction otherTx) return otherTx.Hash.CompareTo(Tx.Hash); } - public int CompareTo(PoolItem otherItem) + public int CompareTo(PoolItem? otherItem) { if (otherItem == null) return 1; return CompareTo(otherItem.Tx); diff --git a/src/Neo/Ledger/TransactionRemovedEventArgs.cs b/src/Neo/Ledger/TransactionRemovedEventArgs.cs index 014695ce26..8cad35127f 100644 --- a/src/Neo/Ledger/TransactionRemovedEventArgs.cs +++ b/src/Neo/Ledger/TransactionRemovedEventArgs.cs @@ -22,7 +22,7 @@ public sealed class TransactionRemovedEventArgs /// /// The s that is being removed. /// - public IReadOnlyCollection Transactions { get; init; } + public required IReadOnlyCollection Transactions { get; init; } /// /// The reason a transaction was removed. diff --git a/src/Neo/Neo.csproj b/src/Neo/Neo.csproj index 64bc409c21..f467a12620 100644 --- a/src/Neo/Neo.csproj +++ b/src/Neo/Neo.csproj @@ -2,6 +2,7 @@ net10.0 + enable NEO;AntShares;Blockchain;Smart Contract diff --git a/src/Neo/NeoSystem.cs b/src/Neo/NeoSystem.cs index 83782fcad8..2e7e16cc64 100644 --- a/src/Neo/NeoSystem.cs +++ b/src/Neo/NeoSystem.cs @@ -37,7 +37,7 @@ public class NeoSystem : IDisposable /// /// Triggered when a service is added to the . /// - public event EventHandler ServiceAdded; + public event EventHandler? ServiceAdded; /// /// The protocol settings of the . @@ -101,7 +101,7 @@ public class NeoSystem : IDisposable private ImmutableList _services = ImmutableList.Empty; private readonly IStore _store; - private ChannelsConfig _startMessage = null; + private ChannelsConfig? _startMessage = null; private int _suspend = 0; static NeoSystem() @@ -124,7 +124,7 @@ static NeoSystem() /// The path of the storage. /// If is the default in-memory storage engine, this parameter is ignored. /// - public NeoSystem(ProtocolSettings settings, string storageProvider = null, string storagePath = null) : + public NeoSystem(ProtocolSettings settings, string? storageProvider = null, string? storagePath = null) : this(settings, StoreFactory.GetStoreProvider(storageProvider ?? nameof(MemoryStore)) ?? throw new ArgumentException($"Can't find the storage provider {storageProvider}", nameof(storageProvider)), storagePath) { @@ -139,7 +139,7 @@ public NeoSystem(ProtocolSettings settings, string storageProvider = null, strin /// The path of the storage. /// If is the default in-memory storage engine, this parameter is ignored. /// - public NeoSystem(ProtocolSettings settings, IStoreProvider storageProvider, string storagePath = null) + public NeoSystem(ProtocolSettings settings, IStoreProvider storageProvider, string? storagePath = null) { Settings = settings; GenesisBlock = CreateGenesisBlock(settings); @@ -217,7 +217,7 @@ public void AddService(object service) /// An action used to filter the service objects. his parameter can be . /// /// The service object found. - public T GetService(Func filter = null) + public T? GetService(Func? filter = null) { var result = _services.OfType(); if (filter is null) diff --git a/src/Neo/Network/P2P/ChannelsConfig.cs b/src/Neo/Network/P2P/ChannelsConfig.cs index f1386318c5..9d0fcb7ce3 100644 --- a/src/Neo/Network/P2P/ChannelsConfig.cs +++ b/src/Neo/Network/P2P/ChannelsConfig.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - using System.Net; namespace Neo.Network.P2P @@ -76,5 +74,3 @@ public class ChannelsConfig public int MaxKnownHashes { get; set; } = DefaultMaxKnownHashes; } } - -#nullable disable diff --git a/src/Neo/Network/P2P/Connection.cs b/src/Neo/Network/P2P/Connection.cs index 9ca016ecba..cfec3efa43 100644 --- a/src/Neo/Network/P2P/Connection.cs +++ b/src/Neo/Network/P2P/Connection.cs @@ -46,7 +46,7 @@ internal class Close { public bool Abort; } public IPEndPoint Local { get; } private ICancelable timer; - private readonly IActorRef tcp; + private readonly IActorRef? tcp; private bool disconnected = false; /// diff --git a/src/Neo/Network/P2P/Helper.cs b/src/Neo/Network/P2P/Helper.cs index b7f42cf190..eed54da7a4 100644 --- a/src/Neo/Network/P2P/Helper.cs +++ b/src/Neo/Network/P2P/Helper.cs @@ -48,7 +48,7 @@ public static UInt256 CalculateHash(this IVerifiable verifiable) /// /// if the hash was successfully retrieved; otherwise, . /// - public static bool TryGetHash(this IVerifiable verifiable, [NotNullWhen(true)] out UInt256 hash) + public static bool TryGetHash(this IVerifiable verifiable, [NotNullWhen(true)] out UInt256? hash) { try { diff --git a/src/Neo/Network/P2P/LocalNode.cs b/src/Neo/Network/P2P/LocalNode.cs index 9e6ed009d5..61847d90c4 100644 --- a/src/Neo/Network/P2P/LocalNode.cs +++ b/src/Neo/Network/P2P/LocalNode.cs @@ -35,17 +35,17 @@ public class LocalNode : Peer /// /// Sent to to relay an . /// - public class RelayDirectly { public IInventory Inventory; } + public record RelayDirectly(IInventory Inventory); /// /// Sent to to send an . /// - public class SendDirectly { public IInventory Inventory; } + public record SendDirectly(IInventory Inventory); /// /// Sent to to request for an instance of . /// - public class GetInstance { } + public record GetInstance; /// /// Indicates the protocol version of the local node. @@ -53,7 +53,7 @@ public class GetInstance { } public const uint ProtocolVersion = 0; private const int MaxCountFromSeedList = 5; - private readonly IPEndPoint[] SeedList; + private readonly IPEndPoint?[] SeedList; private readonly NeoSystem system; internal readonly ConcurrentDictionary RemoteNodes = new(); @@ -108,7 +108,7 @@ public LocalNode(NeoSystem system) /// /// The message command to be packed. /// Optional payload to be Serialized along the message. - private void BroadcastMessage(MessageCommand command, ISerializable payload = null) + private void BroadcastMessage(MessageCommand command, ISerializable? payload = null) { BroadcastMessage(Message.Create(command, payload)); } @@ -132,7 +132,7 @@ private void SendToRemoteNodes(object message) private static IPEndPoint GetIPEndpointFromHostPort(string hostNameOrAddress, int port) { - if (IPAddress.TryParse(hostNameOrAddress, out IPAddress ipAddress)) + if (IPAddress.TryParse(hostNameOrAddress, out var ipAddress)) return new IPEndPoint(ipAddress, port); var entry = hostNameOrAddress.TryCatchThrow(Dns.GetHostEntry); ipAddress = entry.AddressList.FirstOrDefault(p => p.AddressFamily == AddressFamily.InterNetwork || p.IsIPv6Teredo); @@ -140,12 +140,12 @@ private static IPEndPoint GetIPEndpointFromHostPort(string hostNameOrAddress, in return new IPEndPoint(ipAddress, port); } - internal static IPEndPoint GetIpEndPoint(string hostAndPort) + internal static IPEndPoint? GetIpEndPoint(string hostAndPort) { if (string.IsNullOrEmpty(hostAndPort)) return null; return hostAndPort.Split(':') - .TryCatch, Exception, IPEndPoint>( + .TryCatch, Exception, IPEndPoint?>( t => GetIPEndpointFromHostPort(t[0], int.Parse(t[1])), static (_, _) => null); } @@ -159,7 +159,7 @@ internal static IPEndPoint GetIpEndPoint(string hostAndPort) /// if the new connection is allowed; otherwise, . public bool AllowNewConnection(IActorRef actor, RemoteNode node) { - if (node.Version.Network != system.Settings.Network) return false; + if (node.Version!.Network != system.Settings.Network) return false; if (node.Version.Nonce == Nonce) return false; // filter duplicate connections @@ -210,7 +210,11 @@ protected override void NeedMorePeers(int count) // Will call AddPeers with default SeedList set cached on . // It will try to add those, sequentially, to the list of currently unconnected ones. - AddPeers(SeedList.Where(u => u != null).OrderBy(p => RandomNumberFactory.NextInt32()).Take(count)); + AddPeers(SeedList + .Where(p => p != null) + .Select(p => p!) + .OrderBy(p => RandomNumberFactory.NextInt32()) + .Take(count)); } } @@ -236,7 +240,7 @@ protected override void OnReceive(object message) private void OnRelayDirectly(IInventory inventory) { - var message = new RemoteNode.Relay { Inventory = inventory }; + var message = new RemoteNode.Relay(inventory); // When relaying a block, if the block's index is greater than // 'LastBlockIndex' of the RemoteNode, relay the block; // otherwise, don't relay. diff --git a/src/Neo/Network/P2P/Message.cs b/src/Neo/Network/P2P/Message.cs index 0c9c037b8d..05901bfd44 100644 --- a/src/Neo/Network/P2P/Message.cs +++ b/src/Neo/Network/P2P/Message.cs @@ -45,7 +45,7 @@ public class Message : ISerializable /// /// The payload of the message. /// - public ISerializable Payload; + public ISerializable? Payload; private ReadOnlyMemory _payloadRaw; @@ -82,7 +82,7 @@ private static bool ShallICompress(MessageCommand command) /// The command of the message. /// The payload of the message. For the messages that don't require a payload, it should be . /// - public static Message Create(MessageCommand command, ISerializable payload = null) + public static Message Create(MessageCommand command, ISerializable? payload = null) { var tryCompression = ShallICompress(command); @@ -156,7 +156,7 @@ public byte[] ToArray(bool enablecompression) } } - internal static int TryDeserialize(ByteString data, out Message msg) + internal static int TryDeserialize(ByteString data, out Message? msg) { msg = null; if (data.Count < 3) return 0; diff --git a/src/Neo/Network/P2P/Payloads/AddrPayload.cs b/src/Neo/Network/P2P/Payloads/AddrPayload.cs index e13b7ab460..9ce6f0e042 100644 --- a/src/Neo/Network/P2P/Payloads/AddrPayload.cs +++ b/src/Neo/Network/P2P/Payloads/AddrPayload.cs @@ -29,7 +29,7 @@ public class AddrPayload : ISerializable /// /// The list of nodes. /// - public NetworkAddressWithTime[] AddressList; + public required NetworkAddressWithTime[] AddressList; public int Size => AddressList.GetVarSize(); diff --git a/src/Neo/Network/P2P/Payloads/Block.cs b/src/Neo/Network/P2P/Payloads/Block.cs index 07f1de57ae..8caed508d4 100644 --- a/src/Neo/Network/P2P/Payloads/Block.cs +++ b/src/Neo/Network/P2P/Payloads/Block.cs @@ -30,12 +30,12 @@ public sealed class Block : IEquatable, IInventory /// /// The header of the block. /// - public Header Header; + public required Header Header; /// /// The transaction list of the block. /// - public Transaction[] Transactions; + public required Transaction[] Transactions; /// public UInt256 Hash => Header.Hash; @@ -127,14 +127,14 @@ private static Transaction[] DeserializeTransactions(ref MemoryReader reader, in void IVerifiable.DeserializeUnsigned(ref MemoryReader reader) => throw new NotSupportedException(); - public bool Equals(Block other) + public bool Equals(Block? other) { if (ReferenceEquals(this, other)) return true; if (other is null) return false; return Hash.Equals(other.Hash); } - public override bool Equals(object obj) + public override bool Equals(object? obj) { return Equals(obj as Block); } diff --git a/src/Neo/Network/P2P/Payloads/Conditions/AndCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/AndCondition.cs index 664b595bde..ca59faa8dd 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/AndCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/AndCondition.cs @@ -31,13 +31,13 @@ public class AndCondition : WitnessCondition, IEquatable /// /// The expressions of the condition. /// - public WitnessCondition[] Expressions; + public required WitnessCondition[] Expressions; public override int Size => base.Size + Expressions.GetVarSize(); public override WitnessConditionType Type => WitnessConditionType.And; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(AndCondition other) + public bool Equals(AndCondition? other) { if (ReferenceEquals(this, other)) return true; @@ -48,7 +48,7 @@ public bool Equals(AndCondition other) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (obj == null) return false; return obj is AndCondition ac && Equals(ac); @@ -77,10 +77,10 @@ protected override void SerializeWithoutType(BinaryWriter writer) private protected override void ParseJson(JObject json, int maxNestDepth) { - JArray expressions = (JArray)json["expressions"]; + JArray expressions = (JArray)json["expressions"]!; if (expressions.Count > MaxSubitems) throw new FormatException($"`expressions`({expressions.Count}) in AndCondition is out of range (max:{MaxSubitems})"); - Expressions = expressions.Select(p => FromJson((JObject)p, maxNestDepth - 1)).ToArray(); + Expressions = expressions.Select(p => FromJson((JObject)p!, maxNestDepth - 1)).ToArray(); if (Expressions.Length == 0) throw new FormatException("`Expressions` in AndCondition is empty"); } @@ -91,7 +91,7 @@ public override JObject ToJson() return json; } - public override StackItem ToStackItem(IReferenceCounter referenceCounter) + public override StackItem ToStackItem(IReferenceCounter? referenceCounter) { var result = (Array)base.ToStackItem(referenceCounter); result.Add(new Array(referenceCounter, Expressions.Select(p => p.ToStackItem(referenceCounter)))); diff --git a/src/Neo/Network/P2P/Payloads/Conditions/BooleanCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/BooleanCondition.cs index 0538b48e95..885bed5b20 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/BooleanCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/BooleanCondition.cs @@ -32,7 +32,7 @@ public class BooleanCondition : WitnessCondition, IEquatable public override WitnessConditionType Type => WitnessConditionType.Boolean; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(BooleanCondition other) + public bool Equals(BooleanCondition? other) { if (ReferenceEquals(this, other)) return true; @@ -43,7 +43,7 @@ public bool Equals(BooleanCondition other) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (obj == null) return false; return obj is BooleanCondition bc && Equals(bc); @@ -71,7 +71,7 @@ protected override void SerializeWithoutType(BinaryWriter writer) private protected override void ParseJson(JObject json, int maxNestDepth) { - Expression = json["expression"].GetBoolean(); + Expression = json["expression"]!.GetBoolean(); } public override JObject ToJson() @@ -81,7 +81,7 @@ public override JObject ToJson() return json; } - public override StackItem ToStackItem(IReferenceCounter referenceCounter) + public override StackItem ToStackItem(IReferenceCounter? referenceCounter) { var result = (Array)base.ToStackItem(referenceCounter); result.Add(Expression); diff --git a/src/Neo/Network/P2P/Payloads/Conditions/CalledByContractCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/CalledByContractCondition.cs index 0152322e6a..40ca1b9035 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/CalledByContractCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/CalledByContractCondition.cs @@ -27,13 +27,13 @@ public class CalledByContractCondition : WitnessCondition, IEquatable /// The script hash to be checked. /// - public UInt160 Hash; + public required UInt160 Hash; public override int Size => base.Size + UInt160.Length; public override WitnessConditionType Type => WitnessConditionType.CalledByContract; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(CalledByContractCondition other) + public bool Equals(CalledByContractCondition? other) { if (ReferenceEquals(this, other)) return true; @@ -44,7 +44,7 @@ public bool Equals(CalledByContractCondition other) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (obj == null) return false; return obj is CalledByContractCondition cc && Equals(cc); @@ -72,7 +72,7 @@ protected override void SerializeWithoutType(BinaryWriter writer) private protected override void ParseJson(JObject json, int maxNestDepth) { - Hash = UInt160.Parse(json["hash"].GetString()); + Hash = UInt160.Parse(json["hash"]!.GetString()); } public override JObject ToJson() @@ -82,7 +82,7 @@ public override JObject ToJson() return json; } - public override StackItem ToStackItem(IReferenceCounter referenceCounter) + public override StackItem ToStackItem(IReferenceCounter? referenceCounter) { var result = (Array)base.ToStackItem(referenceCounter); result.Add(Hash.ToArray()); diff --git a/src/Neo/Network/P2P/Payloads/Conditions/CalledByEntryCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/CalledByEntryCondition.cs index 8caa824251..e65a6eb096 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/CalledByEntryCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/CalledByEntryCondition.cs @@ -23,7 +23,7 @@ public class CalledByEntryCondition : WitnessCondition, IEquatable WitnessConditionType.CalledByEntry; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(CalledByEntryCondition other) + public bool Equals(CalledByEntryCondition? other) { if (ReferenceEquals(this, other)) return true; @@ -32,7 +32,7 @@ public bool Equals(CalledByEntryCondition other) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (obj == null) return false; return obj is CalledByEntryCondition cc && Equals(cc); @@ -45,7 +45,7 @@ public override int GetHashCode() public override bool Match(ApplicationEngine engine) { - var state = engine.CurrentContext.GetState(); + var state = engine.CurrentContext!.GetState(); if (state.CallingContext is null) return true; state = state.CallingContext.GetState(); return state.CallingContext is null; diff --git a/src/Neo/Network/P2P/Payloads/Conditions/CalledByGroupCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/CalledByGroupCondition.cs index 7e445a00cc..808e5f0b23 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/CalledByGroupCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/CalledByGroupCondition.cs @@ -30,13 +30,13 @@ public class CalledByGroupCondition : WitnessCondition, IEquatable /// The group to be checked. /// - public ECPoint Group; + public required ECPoint Group; public override int Size => base.Size + Group.Size; public override WitnessConditionType Type => WitnessConditionType.CalledByGroup; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(CalledByGroupCondition other) + public bool Equals(CalledByGroupCondition? other) { if (ReferenceEquals(this, other)) return true; @@ -47,7 +47,7 @@ public bool Equals(CalledByGroupCondition other) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (obj == null) return false; return obj is CalledByGroupCondition cc && Equals(cc); @@ -66,7 +66,8 @@ protected override void DeserializeWithoutType(ref MemoryReader reader, int maxN public override bool Match(ApplicationEngine engine) { engine.ValidateCallFlags(CallFlags.ReadStates); - ContractState contract = NativeContract.ContractManagement.GetContract(engine.SnapshotCache, engine.CallingScriptHash); + if (engine.CallingScriptHash is null) return false; + ContractState? contract = NativeContract.ContractManagement.GetContract(engine.SnapshotCache, engine.CallingScriptHash); return contract is not null && contract.Manifest.Groups.Any(p => p.PubKey.Equals(Group)); } @@ -77,7 +78,7 @@ protected override void SerializeWithoutType(BinaryWriter writer) private protected override void ParseJson(JObject json, int maxNestDepth) { - Group = ECPoint.Parse(json["group"].GetString(), ECCurve.Secp256r1); + Group = ECPoint.Parse(json["group"]!.GetString(), ECCurve.Secp256r1); } public override JObject ToJson() @@ -87,7 +88,7 @@ public override JObject ToJson() return json; } - public override StackItem ToStackItem(IReferenceCounter referenceCounter) + public override StackItem ToStackItem(IReferenceCounter? referenceCounter) { var result = (Array)base.ToStackItem(referenceCounter); result.Add(Group.ToArray()); diff --git a/src/Neo/Network/P2P/Payloads/Conditions/GroupCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/GroupCondition.cs index a10fedcef3..686d378ccd 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/GroupCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/GroupCondition.cs @@ -30,13 +30,13 @@ public class GroupCondition : WitnessCondition, IEquatable /// /// The group to be checked. /// - public ECPoint Group; + public required ECPoint Group; public override int Size => base.Size + Group.Size; public override WitnessConditionType Type => WitnessConditionType.Group; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(GroupCondition other) + public bool Equals(GroupCondition? other) { if (ReferenceEquals(this, other)) return true; @@ -47,7 +47,7 @@ public bool Equals(GroupCondition other) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (obj == null) return false; return obj is GroupCondition gc && Equals(gc); @@ -66,7 +66,7 @@ protected override void DeserializeWithoutType(ref MemoryReader reader, int maxN public override bool Match(ApplicationEngine engine) { engine.ValidateCallFlags(CallFlags.ReadStates); - ContractState contract = NativeContract.ContractManagement.GetContract(engine.SnapshotCache, engine.CurrentScriptHash); + ContractState? contract = NativeContract.ContractManagement.GetContract(engine.SnapshotCache, engine.CurrentScriptHash!); return contract is not null && contract.Manifest.Groups.Any(p => p.PubKey.Equals(Group)); } @@ -77,7 +77,7 @@ protected override void SerializeWithoutType(BinaryWriter writer) private protected override void ParseJson(JObject json, int maxNestDepth) { - Group = ECPoint.Parse(json["group"].GetString(), ECCurve.Secp256r1); + Group = ECPoint.Parse(json["group"]!.GetString(), ECCurve.Secp256r1); } public override JObject ToJson() @@ -87,7 +87,7 @@ public override JObject ToJson() return json; } - public override StackItem ToStackItem(IReferenceCounter referenceCounter) + public override StackItem ToStackItem(IReferenceCounter? referenceCounter) { var result = (Array)base.ToStackItem(referenceCounter); result.Add(Group.ToArray()); diff --git a/src/Neo/Network/P2P/Payloads/Conditions/NotCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/NotCondition.cs index 6dbf60cdab..45e6203a3e 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/NotCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/NotCondition.cs @@ -30,13 +30,13 @@ public class NotCondition : WitnessCondition, IEquatable /// /// The expression of the condition to be reversed. /// - public WitnessCondition Expression; + public required WitnessCondition Expression; public override int Size => base.Size + Expression.Size; public override WitnessConditionType Type => WitnessConditionType.Not; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(NotCondition other) + public bool Equals(NotCondition? other) { if (ReferenceEquals(this, other)) return true; @@ -47,7 +47,7 @@ public bool Equals(NotCondition other) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (obj == null) return false; return obj is NotCondition nc && Equals(nc); @@ -75,7 +75,7 @@ protected override void SerializeWithoutType(BinaryWriter writer) private protected override void ParseJson(JObject json, int maxNestDepth) { - Expression = FromJson((JObject)json["expression"], maxNestDepth - 1); + Expression = FromJson((JObject)json["expression"]!, maxNestDepth - 1); } public override JObject ToJson() @@ -85,7 +85,7 @@ public override JObject ToJson() return json; } - public override StackItem ToStackItem(IReferenceCounter referenceCounter) + public override StackItem ToStackItem(IReferenceCounter? referenceCounter) { var result = (Array)base.ToStackItem(referenceCounter); result.Add(Expression.ToStackItem(referenceCounter)); diff --git a/src/Neo/Network/P2P/Payloads/Conditions/OrCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/OrCondition.cs index c878a9b00c..4de9ee6f23 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/OrCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/OrCondition.cs @@ -31,13 +31,13 @@ public class OrCondition : WitnessCondition, IEquatable /// /// The expressions of the condition. /// - public WitnessCondition[] Expressions; + public required WitnessCondition[] Expressions; public override int Size => base.Size + Expressions.GetVarSize(); public override WitnessConditionType Type => WitnessConditionType.Or; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(OrCondition other) + public bool Equals(OrCondition? other) { if (ReferenceEquals(this, other)) return true; @@ -48,7 +48,7 @@ public bool Equals(OrCondition other) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (obj == null) return false; return obj is OrCondition oc && Equals(oc); @@ -77,10 +77,10 @@ protected override void SerializeWithoutType(BinaryWriter writer) private protected override void ParseJson(JObject json, int maxNestDepth) { - JArray expressions = (JArray)json["expressions"]; + JArray expressions = (JArray)json["expressions"]!; if (expressions.Count > MaxSubitems) throw new FormatException($"`expressions`({expressions.Count}) in OrCondition is out of range (max:{MaxSubitems})"); - Expressions = expressions.Select(p => FromJson((JObject)p, maxNestDepth - 1)).ToArray(); + Expressions = expressions.Select(p => FromJson((JObject)p!, maxNestDepth - 1)).ToArray(); if (Expressions.Length == 0) throw new FormatException("`Expressions` in OrCondition is empty"); } @@ -91,7 +91,7 @@ public override JObject ToJson() return json; } - public override StackItem ToStackItem(IReferenceCounter referenceCounter) + public override StackItem ToStackItem(IReferenceCounter? referenceCounter) { var result = (Array)base.ToStackItem(referenceCounter); result.Add(new Array(referenceCounter, Expressions.Select(p => p.ToStackItem(referenceCounter)))); diff --git a/src/Neo/Network/P2P/Payloads/Conditions/ScriptHashCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/ScriptHashCondition.cs index 570cae57b5..cfe18b3b3c 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/ScriptHashCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/ScriptHashCondition.cs @@ -27,13 +27,13 @@ public class ScriptHashCondition : WitnessCondition, IEquatable /// The script hash to be checked. /// - public UInt160 Hash; + public required UInt160 Hash; public override int Size => base.Size + UInt160.Length; public override WitnessConditionType Type => WitnessConditionType.ScriptHash; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(ScriptHashCondition other) + public bool Equals(ScriptHashCondition? other) { if (ReferenceEquals(this, other)) return true; @@ -44,7 +44,7 @@ public bool Equals(ScriptHashCondition other) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (obj == null) return false; return obj is ScriptHashCondition sc && Equals(sc); @@ -72,7 +72,7 @@ protected override void SerializeWithoutType(BinaryWriter writer) private protected override void ParseJson(JObject json, int maxNestDepth) { - Hash = UInt160.Parse(json["hash"].GetString()); + Hash = UInt160.Parse(json["hash"]!.GetString()); } public override JObject ToJson() @@ -82,7 +82,7 @@ public override JObject ToJson() return json; } - public override StackItem ToStackItem(IReferenceCounter referenceCounter) + public override StackItem ToStackItem(IReferenceCounter? referenceCounter) { var result = (Array)base.ToStackItem(referenceCounter); result.Add(Hash.ToArray()); diff --git a/src/Neo/Network/P2P/Payloads/Conditions/WitnessCondition.cs b/src/Neo/Network/P2P/Payloads/Conditions/WitnessCondition.cs index c215ed0f06..0fcd2384c5 100644 --- a/src/Neo/Network/P2P/Payloads/Conditions/WitnessCondition.cs +++ b/src/Neo/Network/P2P/Payloads/Conditions/WitnessCondition.cs @@ -34,7 +34,7 @@ public abstract class WitnessCondition : IInteroperable, ISerializable public virtual int Size => sizeof(WitnessConditionType); - public abstract override bool Equals(object obj); + public abstract override bool Equals(object? obj); public abstract override int GetHashCode(); @@ -115,7 +115,7 @@ public static WitnessCondition FromJson(JObject json, int maxNestDepth) { if (maxNestDepth <= 0) throw new FormatException($"`maxNestDepth`({maxNestDepth}) in WitnessCondition is out of range (min:1)"); - WitnessConditionType type = Enum.Parse(json["type"].GetString()); + WitnessConditionType type = Enum.Parse(json["type"]!.GetString()); if (ReflectionCache.CreateInstance(type) is not WitnessCondition condition) throw new FormatException($"Invalid WitnessConditionType({type})"); condition.ParseJson(json, maxNestDepth); @@ -139,7 +139,7 @@ void IInteroperable.FromStackItem(StackItem stackItem) throw new NotSupportedException(); } - public virtual StackItem ToStackItem(IReferenceCounter referenceCounter) + public virtual StackItem ToStackItem(IReferenceCounter? referenceCounter) { return new Array(referenceCounter, new StackItem[] { (byte)Type }); } diff --git a/src/Neo/Network/P2P/Payloads/Conflicts.cs b/src/Neo/Network/P2P/Payloads/Conflicts.cs index fb6871f474..09df193cc1 100644 --- a/src/Neo/Network/P2P/Payloads/Conflicts.cs +++ b/src/Neo/Network/P2P/Payloads/Conflicts.cs @@ -23,7 +23,7 @@ public class Conflicts : TransactionAttribute /// /// Indicates the conflict transaction hash. /// - public UInt256 Hash; + public required UInt256 Hash; public override TransactionAttributeType Type => TransactionAttributeType.Conflicts; diff --git a/src/Neo/Network/P2P/Payloads/ExtensiblePayload.cs b/src/Neo/Network/P2P/Payloads/ExtensiblePayload.cs index 9ea8445fb8..8633da2076 100644 --- a/src/Neo/Network/P2P/Payloads/ExtensiblePayload.cs +++ b/src/Neo/Network/P2P/Payloads/ExtensiblePayload.cs @@ -28,7 +28,7 @@ public class ExtensiblePayload : IInventory /// /// The category of the extension. /// - public string Category; + public required string Category; /// /// Indicates that the payload is only valid when the block height is greater than or equal to this value. @@ -43,7 +43,7 @@ public class ExtensiblePayload : IInventory /// /// The sender of the payload. /// - public UInt160 Sender; + public required UInt160 Sender; /// /// The data of the payload. @@ -53,22 +53,12 @@ public class ExtensiblePayload : IInventory /// /// The witness of the payload. It must match the . /// - public Witness Witness; + public required Witness Witness; - private UInt256 _hash = null; + private UInt256? _hash = null; /// - public UInt256 Hash - { - get - { - if (_hash == null) - { - _hash = this.CalculateHash(); - } - return _hash; - } - } + public UInt256 Hash => _hash ??= this.CalculateHash(); InventoryType IInventory.InventoryType => InventoryType.Extensible; diff --git a/src/Neo/Network/P2P/Payloads/GetBlocksPayload.cs b/src/Neo/Network/P2P/Payloads/GetBlocksPayload.cs index 2175d6693a..fa44861cab 100644 --- a/src/Neo/Network/P2P/Payloads/GetBlocksPayload.cs +++ b/src/Neo/Network/P2P/Payloads/GetBlocksPayload.cs @@ -24,7 +24,7 @@ public class GetBlocksPayload : ISerializable /// /// The starting hash of the blocks to request. /// - public UInt256 HashStart; + public required UInt256 HashStart; /// /// The number of blocks to request. diff --git a/src/Neo/Network/P2P/Payloads/Header.cs b/src/Neo/Network/P2P/Payloads/Header.cs index a716638484..29fe8bdb9f 100644 --- a/src/Neo/Network/P2P/Payloads/Header.cs +++ b/src/Neo/Network/P2P/Payloads/Header.cs @@ -27,93 +27,52 @@ namespace Neo.Network.P2P.Payloads /// public sealed class Header : IEquatable
, IVerifiable { - private uint version; - private UInt256 prevHash; - private UInt256 merkleRoot; - private ulong timestamp; - private ulong nonce; - private uint index; - private byte primaryIndex; - private UInt160 nextConsensus; - - /// - /// The witness of the block. - /// - public Witness Witness; - /// /// The version of the block. /// - public uint Version - { - get => version; - set { version = value; _hash = null; } - } + public uint Version { get; set { field = value; _hash = null; } } /// /// The hash of the previous block. /// - public UInt256 PrevHash - { - get => prevHash; - set { prevHash = value; _hash = null; } - } + public required UInt256 PrevHash { get; set { field = value; _hash = null; } } /// /// The merkle root of the transactions. /// - public UInt256 MerkleRoot - { - get => merkleRoot; - set { merkleRoot = value; _hash = null; } - } + public required UInt256 MerkleRoot { get; set { field = value; _hash = null; } } /// /// The timestamp of the block. /// - public ulong Timestamp - { - get => timestamp; - set { timestamp = value; _hash = null; } - } + public ulong Timestamp { get; set { field = value; _hash = null; } } /// /// The first eight bytes of random number generated. /// - public ulong Nonce - { - get => nonce; - set { nonce = value; _hash = null; } - } + public ulong Nonce { get; set { field = value; _hash = null; } } /// /// The index of the block. /// - public uint Index - { - get => index; - set { index = value; _hash = null; } - } + public uint Index { get; set { field = value; _hash = null; } } /// /// The primary index of the consensus node that generated this block. /// - public byte PrimaryIndex - { - get => primaryIndex; - set { primaryIndex = value; _hash = null; } - } + public byte PrimaryIndex { get; set { field = value; _hash = null; } } /// /// The multi-signature address of the consensus nodes that generates the next block. /// - public UInt160 NextConsensus - { - get => nextConsensus; - set { nextConsensus = value; _hash = null; } - } + public required UInt160 NextConsensus { get; set { field = value; _hash = null; } } + + /// + /// The witness of the block. + /// + public required Witness Witness; - private UInt256 _hash = null; + private UInt256? _hash = null; /// public UInt256 Hash @@ -165,25 +124,25 @@ public void Deserialize(ref MemoryReader reader) void IVerifiable.DeserializeUnsigned(ref MemoryReader reader) { _hash = null; - version = reader.ReadUInt32(); - if (version > 0) throw new FormatException($"`version`({version}) in Header must be 0"); - prevHash = reader.ReadSerializable(); - merkleRoot = reader.ReadSerializable(); - timestamp = reader.ReadUInt64(); - nonce = reader.ReadUInt64(); - index = reader.ReadUInt32(); - primaryIndex = reader.ReadByte(); - nextConsensus = reader.ReadSerializable(); + Version = reader.ReadUInt32(); + if (Version > 0) throw new FormatException($"`version`({Version}) in Header must be 0"); + PrevHash = reader.ReadSerializable(); + MerkleRoot = reader.ReadSerializable(); + Timestamp = reader.ReadUInt64(); + Nonce = reader.ReadUInt64(); + Index = reader.ReadUInt32(); + PrimaryIndex = reader.ReadByte(); + NextConsensus = reader.ReadSerializable(); } - public bool Equals(Header other) + public bool Equals(Header? other) { if (other is null) return false; if (ReferenceEquals(other, this)) return true; return Hash.Equals(other.Hash); } - public override bool Equals(object obj) + public override bool Equals(object? obj) { return Equals(obj as Header); } @@ -195,10 +154,10 @@ public override int GetHashCode() UInt160[] IVerifiable.GetScriptHashesForVerifying(DataCache snapshot) { - if (prevHash == UInt256.Zero) return [Witness.ScriptHash]; - var prev = NativeContract.Ledger.GetTrimmedBlock(snapshot, prevHash) - ?? throw new InvalidOperationException($"Block {prevHash} was not found"); - return [prev.Header.nextConsensus]; + if (PrevHash == UInt256.Zero) return [Witness.ScriptHash]; + var prev = NativeContract.Ledger.GetTrimmedBlock(snapshot, PrevHash) + ?? throw new InvalidOperationException($"Block {PrevHash} was not found"); + return [prev.Header.NextConsensus]; } public void Serialize(BinaryWriter writer) @@ -209,14 +168,14 @@ public void Serialize(BinaryWriter writer) void IVerifiable.SerializeUnsigned(BinaryWriter writer) { - writer.Write(version); - writer.Write(prevHash); - writer.Write(merkleRoot); - writer.Write(timestamp); - writer.Write(nonce); - writer.Write(index); - writer.Write(primaryIndex); - writer.Write(nextConsensus); + writer.Write(Version); + writer.Write(PrevHash); + writer.Write(MerkleRoot); + writer.Write(Timestamp); + writer.Write(Nonce); + writer.Write(Index); + writer.Write(PrimaryIndex); + writer.Write(NextConsensus); } /// @@ -229,56 +188,56 @@ public JObject ToJson(ProtocolSettings settings) JObject json = new(); json["hash"] = Hash.ToString(); json["size"] = Size; - json["version"] = version; - json["previousblockhash"] = prevHash.ToString(); - json["merkleroot"] = merkleRoot.ToString(); - json["time"] = timestamp; - json["nonce"] = nonce.ToString("X16"); - json["index"] = index; - json["primary"] = primaryIndex; - json["nextconsensus"] = nextConsensus.ToAddress(settings.AddressVersion); + json["version"] = Version; + json["previousblockhash"] = PrevHash.ToString(); + json["merkleroot"] = MerkleRoot.ToString(); + json["time"] = Timestamp; + json["nonce"] = Nonce.ToString("X16"); + json["index"] = Index; + json["primary"] = PrimaryIndex; + json["nextconsensus"] = NextConsensus.ToAddress(settings.AddressVersion); json["witnesses"] = new JArray(Witness.ToJson()); return json; } internal bool Verify(ProtocolSettings settings, DataCache snapshot) { - if (primaryIndex >= settings.ValidatorsCount) + if (PrimaryIndex >= settings.ValidatorsCount) return false; - TrimmedBlock prev = NativeContract.Ledger.GetTrimmedBlock(snapshot, prevHash); + TrimmedBlock? prev = NativeContract.Ledger.GetTrimmedBlock(snapshot, PrevHash); if (prev is null) return false; - if (prev.Index + 1 != index) return false; - if (prev.Hash != prevHash) return false; - if (prev.Header.timestamp >= timestamp) return false; + if (prev.Index + 1 != Index) return false; + if (prev.Hash != PrevHash) return false; + if (prev.Header.Timestamp >= Timestamp) return false; if (!this.VerifyWitnesses(settings, snapshot, 3_00000000L)) return false; return true; } internal bool Verify(ProtocolSettings settings, DataCache snapshot, HeaderCache headerCache) { - Header prev = headerCache.Last; + Header? prev = headerCache.Last; if (prev is null) return Verify(settings, snapshot); - if (primaryIndex >= settings.ValidatorsCount) + if (PrimaryIndex >= settings.ValidatorsCount) return false; - if (prev.Hash != prevHash) return false; - if (prev.index + 1 != index) return false; - if (prev.timestamp >= timestamp) return false; - return this.VerifyWitness(settings, snapshot, prev.nextConsensus, Witness, 3_00000000L, out _); + if (prev.Hash != PrevHash) return false; + if (prev.Index + 1 != Index) return false; + if (prev.Timestamp >= Timestamp) return false; + return this.VerifyWitness(settings, snapshot, prev.NextConsensus, Witness, 3_00000000L, out _); } public Header Clone() { return new Header() { - Version = version, - PrevHash = prevHash, + Version = Version, + PrevHash = PrevHash, MerkleRoot = MerkleRoot, - Timestamp = timestamp, - Nonce = nonce, - Index = index, - PrimaryIndex = primaryIndex, - NextConsensus = nextConsensus, - Witness = Witness?.Clone(), + Timestamp = Timestamp, + Nonce = Nonce, + Index = Index, + PrimaryIndex = PrimaryIndex, + NextConsensus = NextConsensus, + Witness = Witness.Clone(), _hash = _hash }; } diff --git a/src/Neo/Network/P2P/Payloads/HeadersPayload.cs b/src/Neo/Network/P2P/Payloads/HeadersPayload.cs index d573ac8641..9963a87e12 100644 --- a/src/Neo/Network/P2P/Payloads/HeadersPayload.cs +++ b/src/Neo/Network/P2P/Payloads/HeadersPayload.cs @@ -29,7 +29,7 @@ public class HeadersPayload : ISerializable /// /// The list of headers. /// - public Header[] Headers; + public required Header[] Headers; public int Size => Headers.GetVarSize(); diff --git a/src/Neo/Network/P2P/Payloads/InvPayload.cs b/src/Neo/Network/P2P/Payloads/InvPayload.cs index c2c7660183..e4e52dc388 100644 --- a/src/Neo/Network/P2P/Payloads/InvPayload.cs +++ b/src/Neo/Network/P2P/Payloads/InvPayload.cs @@ -35,7 +35,7 @@ public class InvPayload : ISerializable /// /// The hashes of the inventories. /// - public UInt256[] Hashes; + public required UInt256[] Hashes; public int Size => sizeof(InventoryType) + Hashes.GetVarSize(); diff --git a/src/Neo/Network/P2P/Payloads/MerkleBlockPayload.cs b/src/Neo/Network/P2P/Payloads/MerkleBlockPayload.cs index 0900dc4325..358075204e 100644 --- a/src/Neo/Network/P2P/Payloads/MerkleBlockPayload.cs +++ b/src/Neo/Network/P2P/Payloads/MerkleBlockPayload.cs @@ -27,7 +27,7 @@ public class MerkleBlockPayload : ISerializable /// /// The header of the block. /// - public Header Header; + public required Header Header; /// /// The number of the transactions in the block. @@ -37,7 +37,7 @@ public class MerkleBlockPayload : ISerializable /// /// The nodes of the transactions hash tree. /// - public UInt256[] Hashes; + public required UInt256[] Hashes; /// /// The data in the that filtered the block. diff --git a/src/Neo/Network/P2P/Payloads/NetworkAddressWithTime.cs b/src/Neo/Network/P2P/Payloads/NetworkAddressWithTime.cs index aaa88a1564..2b59605bb8 100644 --- a/src/Neo/Network/P2P/Payloads/NetworkAddressWithTime.cs +++ b/src/Neo/Network/P2P/Payloads/NetworkAddressWithTime.cs @@ -32,12 +32,12 @@ public class NetworkAddressWithTime : ISerializable /// /// The address of the node. /// - public IPAddress Address; + public required IPAddress Address; /// /// The capabilities of the node. /// - public NodeCapability[] Capabilities; + public required NodeCapability[] Capabilities; /// /// The of the Tcp server. diff --git a/src/Neo/Network/P2P/Payloads/OracleResponse.cs b/src/Neo/Network/P2P/Payloads/OracleResponse.cs index b126d3c791..d4939b1696 100644 --- a/src/Neo/Network/P2P/Payloads/OracleResponse.cs +++ b/src/Neo/Network/P2P/Payloads/OracleResponse.cs @@ -99,7 +99,7 @@ public override bool Verify(DataCache snapshot, Transaction tx) { if (tx.Signers.Any(p => p.Scopes != WitnessScope.None)) return false; if (!tx.Script.Span.SequenceEqual(FixedScript)) return false; - OracleRequest request = NativeContract.Oracle.GetRequest(snapshot, Id); + OracleRequest? request = NativeContract.Oracle.GetRequest(snapshot, Id); if (request is null) return false; if (tx.NetworkFee + tx.SystemFee != request.GasForResponse) return false; UInt160 oracleAccount = Contract.GetBFTAddress(NativeContract.RoleManagement.GetDesignatedByRole(snapshot, Role.Oracle, NativeContract.Ledger.CurrentIndex(snapshot) + 1)); diff --git a/src/Neo/Network/P2P/Payloads/Signer.cs b/src/Neo/Network/P2P/Payloads/Signer.cs index dc9eb1b7ff..4448bc794a 100644 --- a/src/Neo/Network/P2P/Payloads/Signer.cs +++ b/src/Neo/Network/P2P/Payloads/Signer.cs @@ -37,7 +37,7 @@ public class Signer : IInteroperable, ISerializable, IEquatable /// /// The account of the signer. /// - public UInt160 Account; + public required UInt160 Account; /// /// The scopes of the witness. @@ -48,29 +48,29 @@ public class Signer : IInteroperable, ISerializable, IEquatable /// The contracts that allowed by the witness. /// Only available when the flag is set. /// - public UInt160[] AllowedContracts; + public UInt160[]? AllowedContracts; /// /// The groups that allowed by the witness. /// Only available when the flag is set. /// - public ECPoint[] AllowedGroups; + public ECPoint[]? AllowedGroups; /// /// The rules that the witness must meet. /// Only available when the flag is set. /// - public WitnessRule[] Rules; + public WitnessRule[]? Rules; public int Size => /*Account*/ UInt160.Length + /*Scopes*/ sizeof(WitnessScope) + - /*AllowedContracts*/ (Scopes.HasFlag(WitnessScope.CustomContracts) ? AllowedContracts.GetVarSize() : 0) + - /*AllowedGroups*/ (Scopes.HasFlag(WitnessScope.CustomGroups) ? AllowedGroups.GetVarSize() : 0) + - /*Rules*/ (Scopes.HasFlag(WitnessScope.WitnessRules) ? Rules.GetVarSize() : 0); + /*AllowedContracts*/ (Scopes.HasFlag(WitnessScope.CustomContracts) ? AllowedContracts!.GetVarSize() : 0) + + /*AllowedGroups*/ (Scopes.HasFlag(WitnessScope.CustomGroups) ? AllowedGroups!.GetVarSize() : 0) + + /*Rules*/ (Scopes.HasFlag(WitnessScope.WitnessRules) ? Rules!.GetVarSize() : 0); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(Signer other) + public bool Equals(Signer? other) { if (ReferenceEquals(this, other)) return true; @@ -92,7 +92,7 @@ public bool Equals(Signer other) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override bool Equals(object obj) + public override bool Equals(object? obj) { return obj is Signer signerObj && Equals(signerObj); } @@ -144,7 +144,7 @@ public IEnumerable GetAllRules() } if (Scopes.HasFlag(WitnessScope.CustomContracts)) { - foreach (var hash in AllowedContracts) + foreach (var hash in AllowedContracts!) yield return new WitnessRule { Action = WitnessRuleAction.Allow, @@ -153,7 +153,7 @@ public IEnumerable GetAllRules() } if (Scopes.HasFlag(WitnessScope.CustomGroups)) { - foreach (var group in AllowedGroups) + foreach (var group in AllowedGroups!) yield return new WitnessRule { Action = WitnessRuleAction.Allow, @@ -162,7 +162,7 @@ public IEnumerable GetAllRules() } if (Scopes.HasFlag(WitnessScope.WitnessRules)) { - foreach (var rule in Rules) + foreach (var rule in Rules!) yield return rule; } } @@ -173,11 +173,11 @@ public void Serialize(BinaryWriter writer) writer.Write(Account); writer.Write((byte)Scopes); if (Scopes.HasFlag(WitnessScope.CustomContracts)) - writer.Write(AllowedContracts); + writer.Write(AllowedContracts!); if (Scopes.HasFlag(WitnessScope.CustomGroups)) - writer.Write(AllowedGroups); + writer.Write(AllowedGroups!); if (Scopes.HasFlag(WitnessScope.WitnessRules)) - writer.Write(Rules); + writer.Write(Rules!); } /// @@ -189,15 +189,15 @@ public static Signer FromJson(JObject json) { Signer signer = new() { - Account = UInt160.Parse(json["account"].GetString()), - Scopes = Enum.Parse(json["scopes"].GetString()) + Account = UInt160.Parse(json["account"]!.GetString()), + Scopes = Enum.Parse(json["scopes"]!.GetString()) }; if (signer.Scopes.HasFlag(WitnessScope.CustomContracts)) - signer.AllowedContracts = ((JArray)json["allowedcontracts"]).Select(p => UInt160.Parse(p.GetString())).ToArray(); + signer.AllowedContracts = ((JArray)json["allowedcontracts"]!).Select(p => UInt160.Parse(p!.GetString())).ToArray(); if (signer.Scopes.HasFlag(WitnessScope.CustomGroups)) - signer.AllowedGroups = ((JArray)json["allowedgroups"]).Select(p => ECPoint.Parse(p.GetString(), ECCurve.Secp256r1)).ToArray(); + signer.AllowedGroups = ((JArray)json["allowedgroups"]!).Select(p => ECPoint.Parse(p!.GetString(), ECCurve.Secp256r1)).ToArray(); if (signer.Scopes.HasFlag(WitnessScope.WitnessRules)) - signer.Rules = ((JArray)json["rules"]).Select(p => WitnessRule.FromJson((JObject)p)).ToArray(); + signer.Rules = ((JArray)json["rules"]!).Select(p => WitnessRule.FromJson((JObject)p!)).ToArray(); return signer; } @@ -213,11 +213,11 @@ public JObject ToJson() ["scopes"] = Scopes }; if (Scopes.HasFlag(WitnessScope.CustomContracts)) - json["allowedcontracts"] = AllowedContracts.Select(p => (JToken)p.ToString()).ToArray(); + json["allowedcontracts"] = AllowedContracts!.Select(p => (JToken)p.ToString()).ToArray(); if (Scopes.HasFlag(WitnessScope.CustomGroups)) - json["allowedgroups"] = AllowedGroups.Select(p => (JToken)p.ToString()).ToArray(); + json["allowedgroups"] = AllowedGroups!.Select(p => (JToken)p.ToString()).ToArray(); if (Scopes.HasFlag(WitnessScope.WitnessRules)) - json["rules"] = Rules.Select(p => p.ToJson()).ToArray(); + json["rules"] = Rules!.Select(p => p.ToJson()).ToArray(); return json; } @@ -226,15 +226,15 @@ void IInteroperable.FromStackItem(StackItem stackItem) throw new NotSupportedException(); } - StackItem IInteroperable.ToStackItem(IReferenceCounter referenceCounter) + StackItem IInteroperable.ToStackItem(IReferenceCounter? referenceCounter) { return new Array(referenceCounter, [ Account.ToArray(), (byte)Scopes, - Scopes.HasFlag(WitnessScope.CustomContracts) ? new Array(referenceCounter, AllowedContracts.Select(u => new ByteString(u.ToArray()))) : new Array(referenceCounter), - Scopes.HasFlag(WitnessScope.CustomGroups) ? new Array(referenceCounter, AllowedGroups.Select(u => new ByteString(u.ToArray()))) : new Array(referenceCounter), - Scopes.HasFlag(WitnessScope.WitnessRules) ? new Array(referenceCounter, Rules.Select(u => u.ToStackItem(referenceCounter))) : new Array(referenceCounter) + Scopes.HasFlag(WitnessScope.CustomContracts) ? new Array(referenceCounter, AllowedContracts!.Select(u => new ByteString(u.ToArray()))) : new Array(referenceCounter), + Scopes.HasFlag(WitnessScope.CustomGroups) ? new Array(referenceCounter, AllowedGroups!.Select(u => new ByteString(u.ToArray()))) : new Array(referenceCounter), + Scopes.HasFlag(WitnessScope.WitnessRules) ? new Array(referenceCounter, Rules!.Select(u => u.ToStackItem(referenceCounter))) : new Array(referenceCounter) ]); } diff --git a/src/Neo/Network/P2P/Payloads/Transaction.cs b/src/Neo/Network/P2P/Payloads/Transaction.cs index a8d986f5d5..4e59c1b9c5 100644 --- a/src/Neo/Network/P2P/Payloads/Transaction.cs +++ b/src/Neo/Network/P2P/Payloads/Transaction.cs @@ -46,17 +46,48 @@ public class Transaction : IEquatable, IInventory, IInteroperable /// public const int MaxTransactionAttributes = 16; - private byte version; - private uint nonce; - // In the unit of datoshi, 1 datoshi = 1e-8 GAS - private long sysfee; - // In the unit of datoshi, 1 datoshi = 1e-8 GAS - private long netfee; - private uint validUntilBlock; - private Signer[] _signers; - private TransactionAttribute[] attributes; - private ReadOnlyMemory script; - private Witness[] witnesses; + /// + /// The version of the transaction. + /// + public byte Version { get; set { field = value; _hash = null; } } + + /// + /// The nonce of the transaction. + /// + public uint Nonce { get; set { field = value; _hash = null; } } + + /// + /// The system fee of the transaction. + /// + public long SystemFee { get; set { field = value; _hash = null; } } + + /// + /// The network fee of the transaction. + /// + public long NetworkFee { get; set { field = value; _hash = null; } } + + /// + /// Indicates that the transaction is only valid before this block height. + /// + public uint ValidUntilBlock { get; set { field = value; _hash = null; } } + + /// + /// The signers of the transaction. + /// + public required Signer[] Signers { get; set { field = value; _hash = null; _size = 0; } } + + private Dictionary? _attributesCache; + /// + /// The attributes of the transaction. + /// + public required TransactionAttribute[] Attributes { get; set { field = value; _attributesCache = null; _hash = null; _size = 0; } } + + /// + /// The script of the transaction. + /// + public ReadOnlyMemory Script { get; set { field = value; _hash = null; _size = 0; } } + + public required Witness[] Witnesses { get; set { field = value; _size = 0; } } /// /// The size of a transaction header. @@ -68,22 +99,12 @@ public class Transaction : IEquatable, IInventory, IInteroperable sizeof(long) + //NetworkFee sizeof(uint); //ValidUntilBlock - private Dictionary _attributesCache; - /// - /// The attributes of the transaction. - /// - public TransactionAttribute[] Attributes - { - get => attributes; - set { attributes = value; _attributesCache = null; _hash = null; _size = 0; } - } - /// /// The for the transaction divided by its . /// public long FeePerByte => NetworkFee / Size; - private UInt256 _hash = null; + private UInt256? _hash = null; /// public UInt256 Hash @@ -100,47 +121,11 @@ public UInt256 Hash InventoryType IInventory.InventoryType => InventoryType.TX; - /// - /// The network fee of the transaction. - /// - public long NetworkFee //Distributed to consensus nodes. - { - get => netfee; - set { netfee = value; _hash = null; } - } - - /// - /// The nonce of the transaction. - /// - public uint Nonce - { - get => nonce; - set { nonce = value; _hash = null; } - } - - /// - /// The script of the transaction. - /// - public ReadOnlyMemory Script - { - get => script; - set { script = value; _hash = null; _size = 0; } - } - /// /// The sender is the first signer of the transaction, regardless of its . /// /// Note: The sender will pay the fees of the transaction. - public UInt160 Sender => _signers[0].Account; - - /// - /// The signers of the transaction. - /// - public Signer[] Signers - { - get => _signers; - set { _signers = value; _hash = null; _size = 0; } - } + public UInt160 Sender => Signers[0].Account; private int _size; public int Size @@ -159,39 +144,6 @@ public int Size } } - /// - /// The system fee of the transaction. - /// - public long SystemFee //Fee to be burned. - { - get => sysfee; - set { sysfee = value; _hash = null; } - } - - /// - /// Indicates that the transaction is only valid before this block height. - /// - public uint ValidUntilBlock - { - get => validUntilBlock; - set { validUntilBlock = value; _hash = null; } - } - - /// - /// The version of the transaction. - /// - public byte Version - { - get => version; - set { version = value; _hash = null; } - } - - public Witness[] Witnesses - { - get => witnesses; - set { witnesses = value; _size = 0; } - } - void ISerializable.Deserialize(ref MemoryReader reader) { int startPosition = reader.Position; @@ -254,14 +206,14 @@ public void DeserializeUnsigned(ref MemoryReader reader) if (Script.Length == 0) throw new FormatException("Script in Transaction is empty"); } - public bool Equals(Transaction other) + public bool Equals(Transaction? other) { if (other is null) return false; if (ReferenceEquals(this, other)) return true; return Hash.Equals(other.Hash); } - public override bool Equals(object obj) + public override bool Equals(object? obj) { return Equals(obj as Transaction); } @@ -276,7 +228,7 @@ void IInteroperable.FromStackItem(StackItem stackItem) /// /// The type of the attribute. /// The first attribute of this type. Or if there is no attribute of this type. - public T GetAttribute() where T : TransactionAttribute + public T? GetAttribute() where T : TransactionAttribute { return GetAttributes().FirstOrDefault(); } @@ -288,7 +240,7 @@ public T GetAttribute() where T : TransactionAttribute /// All the attributes of this type. public IEnumerable GetAttributes() where T : TransactionAttribute { - _attributesCache ??= attributes.GroupBy(p => p.GetType()).ToDictionary(p => p.Key, p => p.ToArray()); + _attributesCache ??= Attributes.GroupBy(p => p.GetType()).ToDictionary(p => p.Key, p => p.ToArray()); if (_attributesCache.TryGetValue(typeof(T), out var result)) return result.OfType(); return Enumerable.Empty(); @@ -394,15 +346,15 @@ public virtual VerifyResult VerifyStateDependent(ProtocolSettings settings, Data uint execFeeFactor = NativeContract.Policy.GetExecFeeFactor(snapshot); for (int i = 0; i < hashes.Length; i++) { - if (IsSignatureContract(witnesses[i].VerificationScript.Span) && IsSingleSignatureInvocationScript(witnesses[i].InvocationScript, out var _)) + if (IsSignatureContract(Witnesses[i].VerificationScript.Span) && IsSingleSignatureInvocationScript(Witnesses[i].InvocationScript, out var _)) netFeeDatoshi -= execFeeFactor * SignatureContractCost(); - else if (IsMultiSigContract(witnesses[i].VerificationScript.Span, out int m, out int n) && IsMultiSignatureInvocationScript(m, witnesses[i].InvocationScript, out var _)) + else if (IsMultiSigContract(Witnesses[i].VerificationScript.Span, out int m, out int n) && IsMultiSignatureInvocationScript(m, Witnesses[i].InvocationScript, out var _)) { netFeeDatoshi -= execFeeFactor * MultiSignatureContractCost(m, n); } else { - if (!this.VerifyWitness(settings, snapshot, hashes[i], witnesses[i], netFeeDatoshi, out long fee)) + if (!this.VerifyWitness(settings, snapshot, hashes[i], Witnesses[i], netFeeDatoshi, out long fee)) return VerifyResult.Invalid; netFeeDatoshi -= fee; } @@ -427,10 +379,10 @@ public virtual VerifyResult VerifyStateIndependent(ProtocolSettings settings) { return VerifyResult.InvalidScript; } - UInt160[] hashes = GetScriptHashesForVerifying(null); + UInt160[] hashes = GetScriptHashesForVerifying(null!); for (int i = 0; i < hashes.Length; i++) { - var witness = witnesses[i]; + var witness = Witnesses[i]; if (IsSignatureContract(witness.VerificationScript.Span) && IsSingleSignatureInvocationScript(witness.InvocationScript, out var signature)) { if (hashes[i] != witness.ScriptHash) return VerifyResult.Invalid; @@ -445,7 +397,7 @@ public virtual VerifyResult VerifyStateIndependent(ProtocolSettings settings) return VerifyResult.Invalid; } } - else if (IsMultiSigContract(witness.VerificationScript.Span, out var m, out ECPoint[] points) && IsMultiSignatureInvocationScript(m, witness.InvocationScript, out var signatures)) + else if (IsMultiSigContract(witness.VerificationScript.Span, out var m, out ECPoint[]? points) && IsMultiSignatureInvocationScript(m, witness.InvocationScript, out var signatures)) { if (hashes[i] != witness.ScriptHash) return VerifyResult.Invalid; var n = points.Length; @@ -470,9 +422,9 @@ public virtual VerifyResult VerifyStateIndependent(ProtocolSettings settings) return VerifyResult.Succeed; } - public StackItem ToStackItem(IReferenceCounter referenceCounter) + public StackItem ToStackItem(IReferenceCounter? referenceCounter) { - if (_signers == null || _signers.Length == 0) throw new ArgumentException("Sender is not specified in the transaction."); + if (Signers.Length == 0) throw new ArgumentException("Sender is not specified in the transaction."); return new Array(referenceCounter, new StackItem[] { // Computed properties @@ -490,7 +442,7 @@ public StackItem ToStackItem(IReferenceCounter referenceCounter) } private static bool IsMultiSignatureInvocationScript(int m, ReadOnlyMemory invocationScript, - [NotNullWhen(true)] out ReadOnlyMemory[] sigs) + [NotNullWhen(true)] out ReadOnlyMemory[]? sigs) { sigs = null; ReadOnlySpan span = invocationScript.Span; diff --git a/src/Neo/Network/P2P/Payloads/VersionPayload.cs b/src/Neo/Network/P2P/Payloads/VersionPayload.cs index 1f0fb5aa9a..1a54521a81 100644 --- a/src/Neo/Network/P2P/Payloads/VersionPayload.cs +++ b/src/Neo/Network/P2P/Payloads/VersionPayload.cs @@ -51,7 +51,7 @@ public class VersionPayload : ISerializable /// /// A used to identify the client software of the node. /// - public string UserAgent; + public required string UserAgent; /// /// True if allow compression @@ -61,7 +61,7 @@ public class VersionPayload : ISerializable /// /// The capabilities of the node. /// - public NodeCapability[] Capabilities; + public required NodeCapability[] Capabilities; public int Size => sizeof(uint) + // Network diff --git a/src/Neo/Network/P2P/Payloads/Witness.cs b/src/Neo/Network/P2P/Payloads/Witness.cs index efd92918fa..fe652a6937 100644 --- a/src/Neo/Network/P2P/Payloads/Witness.cs +++ b/src/Neo/Network/P2P/Payloads/Witness.cs @@ -40,20 +40,13 @@ public class Witness : ISerializable /// public ReadOnlyMemory VerificationScript; - private UInt160 _scriptHash; /// /// The hash of the . /// public UInt160 ScriptHash { - get - { - if (_scriptHash == null) - { - _scriptHash = VerificationScript.Span.ToScriptHash(); - } - return _scriptHash; - } + get => field ??= VerificationScript.Span.ToScriptHash(); + private set; } public int Size => InvocationScript.GetVarSize() + VerificationScript.GetVarSize(); @@ -95,7 +88,7 @@ public Witness Clone() { return new Witness() { - _scriptHash = _scriptHash, + ScriptHash = ScriptHash, InvocationScript = InvocationScript.ToArray(), VerificationScript = VerificationScript.ToArray() }; diff --git a/src/Neo/Network/P2P/Payloads/WitnessRule.cs b/src/Neo/Network/P2P/Payloads/WitnessRule.cs index 3ef022241b..ad49eff927 100644 --- a/src/Neo/Network/P2P/Payloads/WitnessRule.cs +++ b/src/Neo/Network/P2P/Payloads/WitnessRule.cs @@ -36,12 +36,12 @@ public class WitnessRule : IInteroperable, ISerializable, IEquatable /// The condition of the rule. /// - public WitnessCondition Condition; + public required WitnessCondition Condition; int ISerializable.Size => sizeof(WitnessRuleAction) + Condition.Size; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(WitnessRule other) + public bool Equals(WitnessRule? other) { if (ReferenceEquals(this, other)) return true; if (other is null) return false; @@ -50,7 +50,7 @@ public bool Equals(WitnessRule other) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (obj == null) return false; return obj is WitnessRule wr && Equals(wr); @@ -82,14 +82,14 @@ void ISerializable.Serialize(BinaryWriter writer) /// The converted . public static WitnessRule FromJson(JObject json) { - WitnessRuleAction action = Enum.Parse(json["action"].GetString()); + WitnessRuleAction action = Enum.Parse(json["action"]!.GetString()); if (action != WitnessRuleAction.Allow && action != WitnessRuleAction.Deny) throw new FormatException($"Invalid action: {action}."); return new() { Action = action, - Condition = WitnessCondition.FromJson((JObject)json["condition"], WitnessCondition.MaxNestingDepth) + Condition = WitnessCondition.FromJson((JObject)json["condition"]!, WitnessCondition.MaxNestingDepth) }; } @@ -111,7 +111,7 @@ void IInteroperable.FromStackItem(StackItem stackItem) throw new NotSupportedException(); } - public StackItem ToStackItem(IReferenceCounter referenceCounter) + public StackItem ToStackItem(IReferenceCounter? referenceCounter) { return new Array(referenceCounter, new StackItem[] { diff --git a/src/Neo/Network/P2P/Peer.cs b/src/Neo/Network/P2P/Peer.cs index 024cb68a73..505ae26e1c 100644 --- a/src/Neo/Network/P2P/Peer.cs +++ b/src/Neo/Network/P2P/Peer.cs @@ -29,42 +29,28 @@ namespace Neo.Network.P2P /// public abstract class Peer : UntypedActor, IWithUnboundedStash { - public IStash Stash { get; set; } + public IStash Stash { get; set; } = null!; /// /// Sent to to add more unconnected peers. /// - public class Peers - { - /// - /// The unconnected peers to be added. - /// - public IEnumerable EndPoints { get; init; } - } + /// The unconnected peers to be added. + public record Peers(IEnumerable EndPoints); /// /// Sent to to connect to a remote node. /// - public class Connect - { - /// - /// The address of the remote node. - /// - public IPEndPoint EndPoint { get; init; } - - /// - /// Indicates whether the remote node is trusted. A trusted node will always be connected. - /// - public bool IsTrusted { get; init; } - } + /// The address of the remote node. + /// Indicates whether the remote node is trusted. A trusted node will always be connected. + public record Connect(IPEndPoint EndPoint, bool IsTrusted); private class Timer { } private static readonly IActorRef s_tcpManager = Context.System.Tcp(); - private IActorRef _tcpListener; + private IActorRef? _tcpListener; - private ICancelable _timer; + private ICancelable _timer = null!; private static readonly HashSet s_localAddresses = new(); @@ -100,7 +86,7 @@ private class Timer { } /// /// Channel configuration. /// - public ChannelsConfig Config { get; private set; } + public ChannelsConfig Config { get; private set; } = null!; /// /// Indicates the maximum number of unconnected peers stored in . @@ -352,7 +338,7 @@ private void OnTcpCommandFailed(Tcp.Command cmd) private void OnTerminated(IActorRef actorRef) { - if (ConnectedPeers.TryRemove(actorRef, out IPEndPoint endPoint)) + if (ConnectedPeers.TryRemove(actorRef, out IPEndPoint? endPoint)) { ConnectedAddresses.TryGetValue(endPoint.Address, out int count); if (count > 0) count--; diff --git a/src/Neo/Network/P2P/RemoteNode.ProtocolHandler.cs b/src/Neo/Network/P2P/RemoteNode.ProtocolHandler.cs index ae01c69d2c..2534498be7 100644 --- a/src/Neo/Network/P2P/RemoteNode.ProtocolHandler.cs +++ b/src/Neo/Network/P2P/RemoteNode.ProtocolHandler.cs @@ -46,7 +46,7 @@ public static event MessageReceivedHandler MessageReceived private readonly HashSetCache _knownHashes; private readonly HashSetCache _sentHashes; private bool _verack = false; - private BloomFilter _bloomFilter; + private BloomFilter? _bloomFilter; private static readonly TimeSpan TimerInterval = TimeSpan.FromSeconds(30); private readonly ICancelable timer = Context.System.Scheduler @@ -61,7 +61,7 @@ private void OnMessage(Message msg) { if (msg.Command != MessageCommand.Version) throw new ProtocolViolationException(); - OnVersionMessageReceived((VersionPayload)msg.Payload); + OnVersionMessageReceived((VersionPayload)msg.Payload!); return; } if (!_verack) @@ -74,53 +74,53 @@ private void OnMessage(Message msg) switch (msg.Command) { case MessageCommand.Addr: - OnAddrMessageReceived((AddrPayload)msg.Payload); + OnAddrMessageReceived((AddrPayload)msg.Payload!); break; case MessageCommand.Block: case MessageCommand.Extensible: - OnInventoryReceived((IInventory)msg.Payload); + OnInventoryReceived((IInventory)msg.Payload!); break; case MessageCommand.FilterAdd: - OnFilterAddMessageReceived((FilterAddPayload)msg.Payload); + OnFilterAddMessageReceived((FilterAddPayload)msg.Payload!); break; case MessageCommand.FilterClear: OnFilterClearMessageReceived(); break; case MessageCommand.FilterLoad: - OnFilterLoadMessageReceived((FilterLoadPayload)msg.Payload); + OnFilterLoadMessageReceived((FilterLoadPayload)msg.Payload!); break; case MessageCommand.GetAddr: OnGetAddrMessageReceived(); break; case MessageCommand.GetBlocks: - OnGetBlocksMessageReceived((GetBlocksPayload)msg.Payload); + OnGetBlocksMessageReceived((GetBlocksPayload)msg.Payload!); break; case MessageCommand.GetBlockByIndex: - OnGetBlockByIndexMessageReceived((GetBlockByIndexPayload)msg.Payload); + OnGetBlockByIndexMessageReceived((GetBlockByIndexPayload)msg.Payload!); break; case MessageCommand.GetData: - OnGetDataMessageReceived((InvPayload)msg.Payload); + OnGetDataMessageReceived((InvPayload)msg.Payload!); break; case MessageCommand.GetHeaders: - OnGetHeadersMessageReceived((GetBlockByIndexPayload)msg.Payload); + OnGetHeadersMessageReceived((GetBlockByIndexPayload)msg.Payload!); break; case MessageCommand.Headers: - OnHeadersMessageReceived((HeadersPayload)msg.Payload); + OnHeadersMessageReceived((HeadersPayload)msg.Payload!); break; case MessageCommand.Inv: - OnInvMessageReceived((InvPayload)msg.Payload); + OnInvMessageReceived((InvPayload)msg.Payload!); break; case MessageCommand.Mempool: OnMemPoolMessageReceived(); break; case MessageCommand.Ping: - OnPingMessageReceived((PingPayload)msg.Payload); + OnPingMessageReceived((PingPayload)msg.Payload!); break; case MessageCommand.Pong: - OnPongMessageReceived((PingPayload)msg.Payload); + OnPongMessageReceived((PingPayload)msg.Payload!); break; case MessageCommand.Transaction: - if (msg.Payload.Size <= Transaction.MaxTransactionSize) + if (msg.Payload!.Size <= Transaction.MaxTransactionSize) OnInventoryReceived((Transaction)msg.Payload); break; case MessageCommand.Verack: @@ -139,10 +139,11 @@ private void OnAddrMessageReceived(AddrPayload payload) ref bool sent = ref _sentCommands[(byte)MessageCommand.GetAddr]; if (!sent) return; sent = false; - _system.LocalNode.Tell(new Peer.Peers - { - EndPoints = payload.AddressList.Select(p => p.EndPoint).Where(p => p.Port > 0) - }); + var endPoints = payload.AddressList + .Select(p => p.EndPoint) + .Where(p => p.Port > 0) + .ToArray(); + _system.LocalNode.Tell(new Peer.Peers(endPoints)); } private void OnFilterAddMessageReceived(FilterAddPayload payload) @@ -172,7 +173,7 @@ private void OnGetAddrMessageReceived() .GroupBy(p => p.Remote.Address, (k, g) => g.First()) .OrderBy(p => RandomNumberFactory.NextInt32()) .Take(AddrPayload.MaxCountToSend); - NetworkAddressWithTime[] networkAddresses = peers.Select(p => NetworkAddressWithTime.Create(p.Listener.Address, p.Version.Timestamp, p.Version.Capabilities)).ToArray(); + NetworkAddressWithTime[] networkAddresses = peers.Select(p => NetworkAddressWithTime.Create(p.Listener.Address, p.Version!.Timestamp, p.Version.Capabilities)).ToArray(); if (networkAddresses.Length == 0) return; EnqueueMessage(Message.Create(MessageCommand.Addr, AddrPayload.Create(networkAddresses))); } @@ -188,8 +189,8 @@ private void OnGetBlocksMessageReceived(GetBlocksPayload payload) // The default value of payload.Count is -1 int count = payload.Count < 0 || payload.Count > InvPayload.MaxHashesCount ? InvPayload.MaxHashesCount : payload.Count; var snapshot = _system.StoreView; - UInt256 hash = payload.HashStart; - TrimmedBlock state = NativeContract.Ledger.GetTrimmedBlock(snapshot, hash); + UInt256? hash = payload.HashStart; + TrimmedBlock? state = NativeContract.Ledger.GetTrimmedBlock(snapshot, hash); if (state == null) return; uint currentHeight = NativeContract.Ledger.CurrentIndex(snapshot); List hashes = new(); @@ -211,7 +212,7 @@ private void OnGetBlockByIndexMessageReceived(GetBlockByIndexPayload payload) uint count = payload.Count == -1 ? InvPayload.MaxHashesCount : Math.Min((uint)payload.Count, InvPayload.MaxHashesCount); for (uint i = payload.IndexStart, max = payload.IndexStart + count; i < max; i++) { - Block block = NativeContract.Ledger.GetBlock(_system.StoreView, i); + Block? block = NativeContract.Ledger.GetBlock(_system.StoreView, i); if (block == null) break; @@ -242,13 +243,13 @@ private void OnGetDataMessageReceived(InvPayload payload) switch (payload.Type) { case InventoryType.TX: - if (_system.MemPool.TryGetValue(hash, out Transaction tx)) + if (_system.MemPool.TryGetValue(hash, out Transaction? tx)) EnqueueMessage(Message.Create(MessageCommand.Transaction, tx)); else notFound.Add(hash); break; case InventoryType.Block: - Block block = NativeContract.Ledger.GetBlock(_system.StoreView, hash); + Block? block = NativeContract.Ledger.GetBlock(_system.StoreView, hash); if (block != null) { if (_bloomFilter == null) @@ -358,7 +359,7 @@ private void OnInvMessageReceived(InvPayload payload) if (hashes.Length == 0) return; foreach (var hash in hashes) _pendingKnownHashes.TryAdd(Tuple.Create(hash, TimeProvider.Current.UtcNow)); - _system.TaskManager.Tell(new TaskManager.NewTasks { Payload = InvPayload.Create(payload.Type, hashes) }); + _system.TaskManager.Tell(new TaskManager.NewTasks(InvPayload.Create(payload.Type, hashes))); } private void OnMemPoolMessageReceived() @@ -381,7 +382,7 @@ private void OnPongMessageReceived(PingPayload payload) private void OnVerackMessageReceived() { _verack = true; - _system.TaskManager.Tell(new TaskManager.Register { Version = Version }); + _system.TaskManager.Tell(new TaskManager.Register(Version!)); CheckMessageQueue(); } @@ -415,7 +416,7 @@ private void OnTimer() var oneMinuteAgo = TimeProvider.Current.UtcNow.AddMinutes(-1); while (_pendingKnownHashes.Count > 0) { - var (_, time) = _pendingKnownHashes.FirstOrDefault; + var (_, time) = _pendingKnownHashes.FirstOrDefault!; if (oneMinuteAgo <= time) break; if (!_pendingKnownHashes.RemoveFirst()) break; } @@ -428,7 +429,7 @@ private void UpdateLastBlockIndex(uint lastBlockIndex) if (lastBlockIndex > LastBlockIndex) { LastBlockIndex = lastBlockIndex; - _system.TaskManager.Tell(new TaskManager.Update { LastBlockIndex = LastBlockIndex }); + _system.TaskManager.Tell(new TaskManager.Update(LastBlockIndex)); } } } diff --git a/src/Neo/Network/P2P/RemoteNode.cs b/src/Neo/Network/P2P/RemoteNode.cs index d3e59434ba..312f8d0971 100644 --- a/src/Neo/Network/P2P/RemoteNode.cs +++ b/src/Neo/Network/P2P/RemoteNode.cs @@ -30,8 +30,8 @@ namespace Neo.Network.P2P /// public partial class RemoteNode : Connection { - internal class StartProtocol { } - internal class Relay { public IInventory Inventory; } + internal record StartProtocol; + internal record Relay(IInventory Inventory); private readonly NeoSystem _system; private readonly LocalNode _localNode; @@ -56,7 +56,7 @@ internal class Relay { public IInventory Inventory; } /// /// The sent by the remote node. /// - public VersionPayload Version { get; private set; } + public VersionPayload? Version { get; private set; } /// /// The index of the last block sent by the remote node. @@ -105,7 +105,7 @@ private void CheckMessageQueue() SendMessage(queue.Dequeue()); } - private void EnqueueMessage(MessageCommand command, ISerializable payload = null) + private void EnqueueMessage(MessageCommand command, ISerializable? payload = null) { EnqueueMessage(Message.Create(command, payload)); } @@ -144,7 +144,7 @@ protected override void OnData(ByteString data) { _messageBuffer = _messageBuffer.Concat(data); - for (Message message = TryParseMessage(); message != null; message = TryParseMessage()) + for (var message = TryParseMessage(); message != null; message = TryParseMessage()) OnMessage(message); } @@ -230,7 +230,7 @@ private void SendMessage(Message message) _sentCommands[(byte)message.Command] = true; } - private Message TryParseMessage() + private Message? TryParseMessage() { var length = Message.TryDeserialize(_messageBuffer, out var msg); if (length <= 0) return null; diff --git a/src/Neo/Network/P2P/TaskManager.cs b/src/Neo/Network/P2P/TaskManager.cs index 3b7c86077c..cdaa3f151e 100644 --- a/src/Neo/Network/P2P/TaskManager.cs +++ b/src/Neo/Network/P2P/TaskManager.cs @@ -31,22 +31,17 @@ namespace Neo.Network.P2P /// public class TaskManager : UntypedActor { - internal class Register { public VersionPayload Version; } - internal class Update { public uint LastBlockIndex; } - internal class NewTasks { public InvPayload Payload; } + internal record Register(VersionPayload Version); + internal record Update(uint LastBlockIndex); + internal record NewTasks(InvPayload Payload); /// /// Sent to to restart tasks for inventories. /// - public class RestartTasks - { - /// - /// The inventories that need to restart. - /// - public InvPayload Payload { get; init; } - } + /// The inventories that need to restart. + public record RestartTasks(InvPayload Payload); - private class Timer { } + private record Timer; private static readonly TimeSpan TimerInterval = TimeSpan.FromSeconds(30); private static readonly TimeSpan TaskTimeout = TimeSpan.FromMinutes(1); @@ -145,7 +140,7 @@ private void OnPersistCompleted(Block block) lastSeenPersistedIndex = block.Index; foreach (var (actor, session) in sessions) - if (session.ReceivedBlock.Remove(block.Index, out Block receivedBlock)) + if (session.ReceivedBlock.Remove(block.Index, out Block? receivedBlock)) { if (block.Hash == receivedBlock.Hash) RequestTasks(actor, session); diff --git a/src/Neo/Network/UPnP.cs b/src/Neo/Network/UPnP.cs index ab701bd1a7..b8c0eb155e 100644 --- a/src/Neo/Network/UPnP.cs +++ b/src/Neo/Network/UPnP.cs @@ -24,7 +24,7 @@ namespace Neo.Network /// public static class UPnP { - private static string s_serviceUrl; + private static string? s_serviceUrl; /// /// Gets or sets the timeout for discovering the UPnP device. @@ -90,7 +90,7 @@ public static bool Discover() return false; } - private static string GetServiceUrl(string resp) + private static string? GetServiceUrl(string resp) { try { @@ -99,13 +99,13 @@ private static string GetServiceUrl(string resp) var nsMgr = new XmlNamespaceManager(desc.NameTable); nsMgr.AddNamespace("tns", "urn:schemas-upnp-org:device-1-0"); var typen = desc.SelectSingleNode("//tns:device/tns:deviceType/text()", nsMgr); - if (!typen.Value.Contains("InternetGatewayDevice")) + if (!typen!.Value!.Contains("InternetGatewayDevice")) return null; var node = desc.SelectSingleNode("//tns:service[contains(tns:serviceType,\"WANIPConnection\")]/tns:controlURL/text()", nsMgr); if (node == null) return null; var eventnode = desc.SelectSingleNode("//tns:service[contains(tns:serviceType,\"WANIPConnection\")]/tns:eventSubURL/text()", nsMgr); - return CombineUrls(resp, node.Value); + return CombineUrls(resp, node.Value!); } catch { return null; } } @@ -164,7 +164,7 @@ public static IPAddress GetExternalIP() "", "GetExternalIPAddress"); var nsMgr = new XmlNamespaceManager(xdoc.NameTable); nsMgr.AddNamespace("tns", "urn:schemas-upnp-org:device-1-0"); - var ip = xdoc.SelectSingleNode("//NewExternalIPAddress/text()", nsMgr).Value; + var ip = xdoc.SelectSingleNode("//NewExternalIPAddress/text()", nsMgr)!.Value!; return IPAddress.Parse(ip); } diff --git a/src/Neo/Persistence/ClonedCache.cs b/src/Neo/Persistence/ClonedCache.cs index 233e6db6eb..b6a7fe2af3 100644 --- a/src/Neo/Persistence/ClonedCache.cs +++ b/src/Neo/Persistence/ClonedCache.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - using Neo.SmartContract; using System.Collections.Generic; @@ -61,5 +59,3 @@ protected override void UpdateInternal(StorageKey key, StorageItem value) } } } - -#nullable disable diff --git a/src/Neo/Persistence/DataCache.cs b/src/Neo/Persistence/DataCache.cs index eaf6866561..0e79ec58ef 100644 --- a/src/Neo/Persistence/DataCache.cs +++ b/src/Neo/Persistence/DataCache.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - using Neo.Extensions; using Neo.SmartContract; using System; @@ -594,5 +592,3 @@ public bool TryGet(StorageKey key, [NotNullWhen(true)] out StorageItem? item) protected abstract void UpdateInternal(StorageKey key, StorageItem value); } } - -#nullable disable diff --git a/src/Neo/Persistence/IReadOnlyStore.cs b/src/Neo/Persistence/IReadOnlyStore.cs index b15ccf4bf7..6b91ad44b3 100644 --- a/src/Neo/Persistence/IReadOnlyStore.cs +++ b/src/Neo/Persistence/IReadOnlyStore.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - using Neo.SmartContract; using System; using System.Collections.Generic; @@ -75,5 +73,3 @@ public TValue this[TKey key] public IEnumerable<(TKey Key, TValue Value)> Find(TKey? keyPrefix = null, SeekDirection direction = SeekDirection.Forward); } } - -#nullable disable diff --git a/src/Neo/Persistence/IStore.cs b/src/Neo/Persistence/IStore.cs index 6a79ff0549..47a3ed523f 100644 --- a/src/Neo/Persistence/IStore.cs +++ b/src/Neo/Persistence/IStore.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - using System; namespace Neo.Persistence @@ -42,5 +40,3 @@ public interface IStore : IStoreSnapshot GetSnapshot(); } } - -#nullable disable diff --git a/src/Neo/Persistence/IStoreProvider.cs b/src/Neo/Persistence/IStoreProvider.cs index d14be6ff44..a827bcea77 100644 --- a/src/Neo/Persistence/IStoreProvider.cs +++ b/src/Neo/Persistence/IStoreProvider.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - namespace Neo.Persistence { /// @@ -28,8 +26,6 @@ public interface IStoreProvider /// /// The path of the database. /// The created instance. - IStore GetStore(string path); + IStore GetStore(string? path); } } - -#nullable disable diff --git a/src/Neo/Persistence/IStoreSnapshot.cs b/src/Neo/Persistence/IStoreSnapshot.cs index 95ad2df1fa..bed1235787 100644 --- a/src/Neo/Persistence/IStoreSnapshot.cs +++ b/src/Neo/Persistence/IStoreSnapshot.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - using System; namespace Neo.Persistence @@ -34,5 +32,3 @@ public interface IStoreSnapshot : void Commit(); } } - -#nullable disable diff --git a/src/Neo/Persistence/IWriteStore.cs b/src/Neo/Persistence/IWriteStore.cs index ba0773dce2..9768a8843b 100644 --- a/src/Neo/Persistence/IWriteStore.cs +++ b/src/Neo/Persistence/IWriteStore.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - namespace Neo.Persistence { /// @@ -39,5 +37,3 @@ public interface IWriteStore void PutSync(TKey key, TValue value) => Put(key, value); } } - -#nullable disable diff --git a/src/Neo/Persistence/Providers/MemorySnapshot.cs b/src/Neo/Persistence/Providers/MemorySnapshot.cs index c554a17d3e..362f08472e 100644 --- a/src/Neo/Persistence/Providers/MemorySnapshot.cs +++ b/src/Neo/Persistence/Providers/MemorySnapshot.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - using Neo.Extensions; using System.Collections.Concurrent; using System.Collections.Generic; @@ -97,5 +95,3 @@ public bool Contains(byte[] key) } } } - -#nullable disable diff --git a/src/Neo/Persistence/Providers/MemoryStore.cs b/src/Neo/Persistence/Providers/MemoryStore.cs index cbe8f3d748..ff5972aac5 100644 --- a/src/Neo/Persistence/Providers/MemoryStore.cs +++ b/src/Neo/Persistence/Providers/MemoryStore.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - using Neo.Extensions; using System.Collections.Concurrent; using System.Collections.Generic; @@ -94,5 +92,3 @@ internal void Reset() } } } - -#nullable disable diff --git a/src/Neo/Persistence/Providers/MemoryStoreProvider.cs b/src/Neo/Persistence/Providers/MemoryStoreProvider.cs index c53b599264..337c88dd34 100644 --- a/src/Neo/Persistence/Providers/MemoryStoreProvider.cs +++ b/src/Neo/Persistence/Providers/MemoryStoreProvider.cs @@ -9,15 +9,11 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - namespace Neo.Persistence.Providers { public class MemoryStoreProvider : IStoreProvider { public string Name => nameof(MemoryStore); - public IStore GetStore(string path) => new MemoryStore(); + public IStore GetStore(string? path) => new MemoryStore(); } } - -#nullable disable diff --git a/src/Neo/Persistence/StoreCache.cs b/src/Neo/Persistence/StoreCache.cs index b1905e706d..58aefbbbb7 100644 --- a/src/Neo/Persistence/StoreCache.cs +++ b/src/Neo/Persistence/StoreCache.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - using Neo.Extensions; using Neo.SmartContract; using System; @@ -106,5 +104,3 @@ protected override StorageItem GetInternal(StorageKey key) #endregion } } - -#nullable disable diff --git a/src/Neo/Persistence/StoreFactory.cs b/src/Neo/Persistence/StoreFactory.cs index f8e8db219c..f869a6d17f 100644 --- a/src/Neo/Persistence/StoreFactory.cs +++ b/src/Neo/Persistence/StoreFactory.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - using Neo.Persistence.Providers; using System.Collections.Generic; @@ -67,5 +65,3 @@ public static IStore GetStore(string storageProvider, string path) } } } - -#nullable disable diff --git a/src/Neo/Plugins/Plugin.cs b/src/Neo/Plugins/Plugin.cs index 742b284439..0140659096 100644 --- a/src/Neo/Plugins/Plugin.cs +++ b/src/Neo/Plugins/Plugin.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - using Microsoft.Extensions.Configuration; using System; using System.Collections.Generic; @@ -287,5 +285,3 @@ public static bool SendMessage(object message) } } } - -#nullable disable diff --git a/src/Neo/ProtocolSettings.cs b/src/Neo/ProtocolSettings.cs index 1e547e83f6..759ce1278b 100644 --- a/src/Neo/ProtocolSettings.cs +++ b/src/Neo/ProtocolSettings.cs @@ -40,7 +40,7 @@ public record ProtocolSettings /// /// The public keys of the standby committee members. /// - public IReadOnlyList StandbyCommittee { get; init; } + public required IReadOnlyList StandbyCommittee { get; init; } /// /// The number of members of the committee in NEO system. @@ -55,7 +55,7 @@ public record ProtocolSettings /// /// The default seed nodes list. /// - public string[] SeedList { get; init; } + public required string[] SeedList { get; init; } /// /// Indicates the time in milliseconds between two blocks. Note that starting from @@ -99,7 +99,7 @@ public record ProtocolSettings /// /// Sets the block height from which a hardfork is activated. /// - public ImmutableDictionary Hardforks { get; init; } + public required ImmutableDictionary Hardforks { get; init; } /// /// Indicates the amount of gas to distribute during initialization. @@ -107,11 +107,10 @@ public record ProtocolSettings /// public ulong InitialGasDistribution { get; init; } - private IReadOnlyList _standbyValidators; /// /// The public keys of the standby validators. /// - public IReadOnlyList StandbyValidators => _standbyValidators ??= StandbyCommittee.Take(ValidatorsCount).ToArray(); + public IReadOnlyList StandbyValidators => field ??= StandbyCommittee.Take(ValidatorsCount).ToArray(); /// /// The default protocol settings for NEO MainNet. @@ -132,7 +131,7 @@ public record ProtocolSettings Hardforks = EnsureOmmitedHardforks(new Dictionary()).ToImmutableDictionary() }; - public static ProtocolSettings Custom { get; set; } + public static ProtocolSettings? Custom { get; set; } /// /// Searches for a file in the given path. If not found, checks in the executable directory. @@ -140,7 +139,7 @@ public record ProtocolSettings /// The name of the file to search for. /// The primary path to search in. /// Full path of the file if found, null otherwise. - public static string FindFile(string fileName, string path) + public static string? FindFile(string fileName, string path) { // Check if the given path is relative if (!Path.IsPathRooted(path)) @@ -188,14 +187,14 @@ public static ProtocolSettings Load(Stream stream) /// The loaded . public static ProtocolSettings Load(string path) { - path = FindFile(path, Environment.CurrentDirectory); + string? fullpath = FindFile(path, Environment.CurrentDirectory); - if (path is null) + if (fullpath is null) { return Default; } - using var stream = File.OpenRead(path); + using var stream = File.OpenRead(fullpath); return Load(stream); } @@ -211,11 +210,11 @@ public static ProtocolSettings Load(IConfigurationSection section) Network = section.GetValue("Network", Default.Network), AddressVersion = section.GetValue("AddressVersion", Default.AddressVersion), StandbyCommittee = section.GetSection("StandbyCommittee").Exists() - ? section.GetSection("StandbyCommittee").GetChildren().Select(p => ECPoint.Parse(p.Get(), ECCurve.Secp256r1)).ToArray() + ? section.GetSection("StandbyCommittee").GetChildren().Select(p => ECPoint.Parse(p.Get()!, ECCurve.Secp256r1)).ToArray() : Default.StandbyCommittee, ValidatorsCount = section.GetValue("ValidatorsCount", Default.ValidatorsCount), SeedList = section.GetSection("SeedList").Exists() - ? section.GetSection("SeedList").GetChildren().Select(p => p.Get()).ToArray() + ? section.GetSection("SeedList").GetChildren().Select(p => p.Get()!).ToArray() : Default.SeedList, MillisecondsPerBlock = section.GetValue("MillisecondsPerBlock", Default.MillisecondsPerBlock), MaxTransactionsPerBlock = section.GetValue("MaxTransactionsPerBlock", Default.MaxTransactionsPerBlock), @@ -224,7 +223,7 @@ public static ProtocolSettings Load(IConfigurationSection section) MaxValidUntilBlockIncrement = section.GetValue("MaxValidUntilBlockIncrement", Default.MaxValidUntilBlockIncrement), InitialGasDistribution = section.GetValue("InitialGasDistribution", Default.InitialGasDistribution), Hardforks = section.GetSection("Hardforks").Exists() - ? EnsureOmmitedHardforks(section.GetSection("Hardforks").GetChildren().ToDictionary(p => Enum.Parse(p.Key, true), p => uint.Parse(p.Value))).ToImmutableDictionary() + ? EnsureOmmitedHardforks(section.GetSection("Hardforks").GetChildren().ToDictionary(p => Enum.Parse(p.Key, true), p => uint.Parse(p.Value!))).ToImmutableDictionary() : Default.Hardforks }; CheckingHardfork(Custom); diff --git a/src/Neo/Sign/SignException.cs b/src/Neo/Sign/SignException.cs index e734b6fb66..7128a25503 100644 --- a/src/Neo/Sign/SignException.cs +++ b/src/Neo/Sign/SignException.cs @@ -23,6 +23,6 @@ public class SignException : Exception /// /// The message that describes the error. /// The cause of the exception. - public SignException(string message, Exception cause = null) : base(message, cause) { } + public SignException(string message, Exception? cause = null) : base(message, cause) { } } } diff --git a/src/Neo/Sign/SignerManager.cs b/src/Neo/Sign/SignerManager.cs index f442cac7cc..1f763b68fa 100644 --- a/src/Neo/Sign/SignerManager.cs +++ b/src/Neo/Sign/SignerManager.cs @@ -26,7 +26,7 @@ public static class SignerManager /// /// The signer; if not found or no signer or multiple signers are registered. /// - public static ISigner GetSignerOrDefault(string name) + public static ISigner? GetSignerOrDefault(string name) { if (!string.IsNullOrEmpty(name) && s_signers.TryGetValue(name, out var signer)) return signer; if (s_signers.Count == 1) return s_signers.Values.First(); diff --git a/src/Neo/SmartContract/ApplicationEngine.Contract.cs b/src/Neo/SmartContract/ApplicationEngine.Contract.cs index 0ec783cc08..05562604fc 100644 --- a/src/Neo/SmartContract/ApplicationEngine.Contract.cs +++ b/src/Neo/SmartContract/ApplicationEngine.Contract.cs @@ -76,9 +76,9 @@ protected internal void CallContract(UInt160 contractHash, string method, CallFl if ((callFlags & ~CallFlags.All) != 0) throw new ArgumentOutOfRangeException(nameof(callFlags)); - ContractState contract = NativeContract.ContractManagement.GetContract(SnapshotCache, contractHash); + ContractState? contract = NativeContract.ContractManagement.GetContract(SnapshotCache, contractHash); if (contract is null) throw new InvalidOperationException($"Called Contract Does Not Exist: {contractHash}.{method}"); - ContractMethodDescriptor md = contract.Manifest.Abi.GetMethod(method, args.Count); + ContractMethodDescriptor? md = contract.Manifest.Abi.GetMethod(method, args.Count); if (md is null) throw new InvalidOperationException($"Method \"{method}\" with {args.Count} parameter(s) doesn't exist in the contract {contractHash}."); bool hasReturnValue = md.ReturnType != ContractParameterType.Void; @@ -93,7 +93,7 @@ protected internal void CallContract(UInt160 contractHash, string method, CallFl /// The version of the native contract to be called. protected internal void CallNativeContract(byte version) { - NativeContract contract = NativeContract.GetContract(CurrentScriptHash); + NativeContract? contract = NativeContract.GetContract(CurrentScriptHash!); if (contract is null) throw new InvalidOperationException("It is not allowed to use \"System.Contract.CallNative\" directly."); if (!contract.IsActive(ProtocolSettings, NativeContract.Ledger.CurrentIndex(SnapshotCache))) @@ -108,7 +108,7 @@ protected internal void CallNativeContract(byte version) /// The of the current context. protected internal CallFlags GetCallFlags() { - var state = CurrentContext.GetState(); + var state = CurrentContext!.GetState(); return state.CallFlags; } @@ -157,7 +157,7 @@ protected internal async void NativeOnPersistAsync() throw new InvalidOperationException(); foreach (NativeContract contract in NativeContract.Contracts) { - if (contract.IsActive(ProtocolSettings, PersistingBlock.Index)) + if (contract.IsActive(ProtocolSettings, PersistingBlock!.Index)) await contract.OnPersistAsync(this); } } @@ -179,7 +179,7 @@ protected internal async void NativePostPersistAsync() throw new InvalidOperationException(); foreach (NativeContract contract in NativeContract.Contracts) { - if (contract.IsActive(ProtocolSettings, PersistingBlock.Index)) + if (contract.IsActive(ProtocolSettings, PersistingBlock!.Index)) await contract.PostPersistAsync(this); } } diff --git a/src/Neo/SmartContract/ApplicationEngine.Crypto.cs b/src/Neo/SmartContract/ApplicationEngine.Crypto.cs index a190cfdd0d..b8fdb62ba0 100644 --- a/src/Neo/SmartContract/ApplicationEngine.Crypto.cs +++ b/src/Neo/SmartContract/ApplicationEngine.Crypto.cs @@ -47,7 +47,7 @@ protected internal bool CheckSig(byte[] pubkey, byte[] signature) { try { - return Crypto.VerifySignature(ScriptContainer.GetSignData(ProtocolSettings.Network), signature, pubkey, ECCurve.Secp256r1); + return Crypto.VerifySignature(ScriptContainer!.GetSignData(ProtocolSettings.Network), signature, pubkey, ECCurve.Secp256r1); } catch (ArgumentException) { @@ -64,7 +64,7 @@ protected internal bool CheckSig(byte[] pubkey, byte[] signature) /// if the signatures are valid; otherwise, . protected internal bool CheckMultisig(byte[][] pubkeys, byte[][] signatures) { - var message = ScriptContainer.GetSignData(ProtocolSettings.Network); + var message = ScriptContainer!.GetSignData(ProtocolSettings.Network); int m = signatures.Length, n = pubkeys.Length; if (n == 0) throw new ArgumentException("pubkeys array cannot be empty."); if (m == 0) throw new ArgumentException("signatures array cannot be empty."); diff --git a/src/Neo/SmartContract/ApplicationEngine.Helper.cs b/src/Neo/SmartContract/ApplicationEngine.Helper.cs index 3b18a5e3f4..c12fd9b84c 100644 --- a/src/Neo/SmartContract/ApplicationEngine.Helper.cs +++ b/src/Neo/SmartContract/ApplicationEngine.Helper.cs @@ -26,13 +26,13 @@ public string GetEngineStackInfoOnFault(bool exceptionStackTrace = true, bool ex StringBuilder traceback = new(); if (CallingScriptHash != null) traceback.AppendLine($"CallingScriptHash={CallingScriptHash}[{NativeContract.ContractManagement.GetContract(SnapshotCache, CallingScriptHash)?.Manifest.Name}]"); - traceback.AppendLine($"CurrentScriptHash={CurrentScriptHash}[{NativeContract.ContractManagement.GetContract(SnapshotCache, CurrentScriptHash)?.Manifest.Name}]"); + traceback.AppendLine($"CurrentScriptHash={CurrentScriptHash}[{NativeContract.ContractManagement.GetContract(SnapshotCache, CurrentScriptHash!)?.Manifest.Name}]"); traceback.AppendLine($"EntryScriptHash={EntryScriptHash}"); foreach (ExecutionContext context in InvocationStack.Reverse()) { UInt160 contextScriptHash = context.GetScriptHash(); - string contextContractName = NativeContract.ContractManagement.GetContract(SnapshotCache, contextScriptHash)?.Manifest.Name; + string? contextContractName = NativeContract.ContractManagement.GetContract(SnapshotCache, contextScriptHash)?.Manifest.Name; traceback.AppendLine($"\tInstructionPointer={context.InstructionPointer}, OpCode {context.CurrentInstruction?.OpCode}, Script Length={context.Script.Length} {contextScriptHash}[{contextContractName}]"); } traceback.Append(GetEngineExceptionInfo(exceptionStackTrace: exceptionStackTrace, exceptionMessage: exceptionMessage)); diff --git a/src/Neo/SmartContract/ApplicationEngine.Runtime.cs b/src/Neo/SmartContract/ApplicationEngine.Runtime.cs index 9aca67043d..2b813338d0 100644 --- a/src/Neo/SmartContract/ApplicationEngine.Runtime.cs +++ b/src/Neo/SmartContract/ApplicationEngine.Runtime.cs @@ -194,6 +194,8 @@ internal protected byte GetAddressVersion() /// The timestamp of the current block. protected internal ulong GetTime() { + if (PersistingBlock is null) + throw new InvalidOperationException("GetTime can only be called with Application trigger."); return PersistingBlock.Timestamp; } @@ -217,7 +219,7 @@ protected internal void RuntimeLoadScript(byte[] script, CallFlags callFlags, Ar if ((callFlags & ~CallFlags.All) != 0) throw new ArgumentOutOfRangeException(nameof(callFlags), $"Invalid call flags: {callFlags}"); - ExecutionContextState state = CurrentContext.GetState(); + ExecutionContextState state = CurrentContext!.GetState(); ExecutionContext context = LoadScript(new Script(script, true), configureState: p => { p.CallingContext = CurrentContext; @@ -258,17 +260,17 @@ protected internal bool CheckWitnessInternal(UInt160 hash) if (ScriptContainer is Transaction tx) { Signer[] signers; - OracleResponse response = tx.GetAttribute(); + OracleResponse? response = tx.GetAttribute(); if (response is null) { signers = tx.Signers; } else { - OracleRequest request = NativeContract.Oracle.GetRequest(SnapshotCache, response.Id); - signers = NativeContract.Ledger.GetTransaction(SnapshotCache, request.OriginalTxid).Signers; + OracleRequest request = NativeContract.Oracle.GetRequest(SnapshotCache, response.Id)!; + signers = NativeContract.Ledger.GetTransaction(SnapshotCache, request.OriginalTxid)!.Signers; } - Signer signer = signers.FirstOrDefault(p => p.Account.Equals(hash)); + Signer? signer = signers.FirstOrDefault(p => p.Account.Equals(hash)); if (signer is null) return false; foreach (WitnessRule rule in signer.GetAllRules()) { @@ -295,9 +297,9 @@ protected internal bool CheckWitnessInternal(UInt160 hash) /// The number of times the current contract has been called during the execution. protected internal int GetInvocationCounter() { - if (!invocationCounter.TryGetValue(CurrentScriptHash, out var counter)) + if (!invocationCounter.TryGetValue(CurrentScriptHash!, out var counter)) { - invocationCounter[CurrentScriptHash] = counter = 1; + invocationCounter[CurrentScriptHash!] = counter = 1; } return counter; } @@ -338,7 +340,7 @@ protected internal void RuntimeLog(byte[] state) try { string message = state.ToStrictUtf8String(); - Log?.Invoke(this, new LogEventArgs(ScriptContainer, CurrentScriptHash, message)); + Log?.Invoke(this, new LogEventArgs(ScriptContainer, CurrentScriptHash!, message)); } catch { @@ -363,7 +365,7 @@ protected internal void RuntimeNotify(byte[] eventName, Array state) throw new ArgumentException($"Event name size {eventName.Length} exceeds maximum allowed size of {MaxEventName} bytes", nameof(eventName)); string name = eventName.ToStrictUtf8String(); - ContractState contract = CurrentContext.GetState().Contract; + ContractState? contract = CurrentContext!.GetState().Contract; if (contract is null) throw new InvalidOperationException("Notifications are not allowed in dynamic scripts."); var @event = contract.Manifest.Abi.Events.FirstOrDefault(p => string.Equals(p.Name, name, StringComparison.Ordinal)); @@ -380,19 +382,19 @@ protected internal void RuntimeNotify(byte[] eventName, Array state) using MemoryStream ms = new(MaxNotificationSize); using BinaryWriter writer = new(ms, Utility.StrictUTF8, true); BinarySerializer.Serialize(writer, state, MaxNotificationSize, Limits.MaxStackSize); - SendNotification(CurrentScriptHash, name, state); + SendNotification(CurrentScriptHash!, name, state); } protected internal void RuntimeNotifyV1(byte[] eventName, Array state) { if (eventName.Length > MaxEventName) throw new ArgumentException($"Event name size {eventName.Length} exceeds maximum allowed size of {MaxEventName} bytes", nameof(eventName)); - if (CurrentContext.GetState().Contract is null) + if (CurrentContext!.GetState().Contract is null) throw new InvalidOperationException("Notifications are not allowed in dynamic scripts."); using MemoryStream ms = new(MaxNotificationSize); using BinaryWriter writer = new(ms, Utility.StrictUTF8, true); BinarySerializer.Serialize(writer, state, MaxNotificationSize, Limits.MaxStackSize); - SendNotification(CurrentScriptHash, eventName.ToStrictUtf8String(), state); + SendNotification(CurrentScriptHash!, eventName.ToStrictUtf8String(), state); } /// @@ -414,7 +416,7 @@ protected internal void SendNotification(UInt160 hash, string eventName, Array s NotifyEventArgs notification = new(ScriptContainer, hash, eventName, (Array)state.DeepCopy(asImmutable: true)); Notify?.Invoke(this, notification); notifications.Add(notification); - CurrentContext.GetState().NotificationCount++; + CurrentContext!.GetState().NotificationCount++; } /// @@ -454,7 +456,7 @@ protected internal void BurnGas(long datoshi) /// Get the Signers of the current transaction. /// /// The signers of the current transaction, or null if is not related to a transaction execution. - protected internal Signer[] GetCurrentSigners() + protected internal Signer[]? GetCurrentSigners() { if (ScriptContainer is Transaction tx) return tx.Signers; diff --git a/src/Neo/SmartContract/ApplicationEngine.Storage.cs b/src/Neo/SmartContract/ApplicationEngine.Storage.cs index d04f5b8a8f..36c3769893 100644 --- a/src/Neo/SmartContract/ApplicationEngine.Storage.cs +++ b/src/Neo/SmartContract/ApplicationEngine.Storage.cs @@ -14,8 +14,6 @@ using Neo.SmartContract.Native; using System; -#nullable enable - namespace Neo.SmartContract { partial class ApplicationEngine @@ -103,7 +101,8 @@ partial class ApplicationEngine /// The storage context for the current contract. protected internal StorageContext GetStorageContext() { - ContractState contract = NativeContract.ContractManagement.GetContract(SnapshotCache, CurrentScriptHash); + ContractState contract = NativeContract.ContractManagement.GetContract(SnapshotCache, CurrentScriptHash!) + ?? throw new InvalidOperationException("This method can only be called by a deployed contract."); return new StorageContext { Id = contract.Id, @@ -118,7 +117,8 @@ protected internal StorageContext GetStorageContext() /// The storage context for the current contract. protected internal StorageContext GetReadOnlyContext() { - ContractState contract = NativeContract.ContractManagement.GetContract(SnapshotCache, CurrentScriptHash); + ContractState contract = NativeContract.ContractManagement.GetContract(SnapshotCache, CurrentScriptHash!) + ?? throw new InvalidOperationException("This method can only be called by a deployed contract."); return new StorageContext { Id = contract.Id, @@ -299,5 +299,3 @@ protected internal void DeleteLocal(byte[] key) } } } - -#nullable disable diff --git a/src/Neo/SmartContract/ApplicationEngine.cs b/src/Neo/SmartContract/ApplicationEngine.cs index e69c638dcf..e3b10b746d 100644 --- a/src/Neo/SmartContract/ApplicationEngine.cs +++ b/src/Neo/SmartContract/ApplicationEngine.cs @@ -20,6 +20,7 @@ using Neo.VM.Types; using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; using System.Numerics; using System.Reflection; @@ -51,26 +52,26 @@ public partial class ApplicationEngine : ExecutionEngine /// /// Triggered when a contract calls System.Runtime.Notify. /// - public event OnNotifyEvent Notify; + public event OnNotifyEvent? Notify; /// /// Triggered when a contract calls System.Runtime.Log. /// - public event OnLogEvent Log; + public event OnLogEvent? Log; /// /// On Application Engine /// - public static OnInstanceHandlerEvent InstanceHandler; + public static OnInstanceHandlerEvent? InstanceHandler; - private static Dictionary services; + private static Dictionary? services; // Total amount of GAS spent to execute. // In the unit of datoshi, 1 datoshi = 1e-8 GAS, 1 GAS = 1e8 datoshi private readonly long _feeAmount; - private Dictionary states; + private Dictionary? states; private readonly DataCache originalSnapshotCache; - private List notifications; - private List disposables; + private List? notifications; + private List? disposables; private readonly Dictionary invocationCounter = new(); private readonly Dictionary contractTasks = new(); internal readonly uint ExecFeeFactor; @@ -81,17 +82,17 @@ public partial class ApplicationEngine : ExecutionEngine /// /// Gets or sets the provider used to create the . /// - public static IApplicationEngineProvider Provider { get; set; } + public static IApplicationEngineProvider? Provider { get; set; } /// /// Gets the descriptors of all interoperable services available in NEO. /// - public static IReadOnlyDictionary Services => services; + public static IReadOnlyDictionary Services => services ?? (IReadOnlyDictionary)ImmutableDictionary.Empty; /// /// The diagnostic used by the engine. This property can be . /// - public IDiagnostic Diagnostic { get; } + public IDiagnostic? Diagnostic { get; } private List Disposables => disposables ??= new List(); @@ -103,7 +104,7 @@ public partial class ApplicationEngine : ExecutionEngine /// /// The container that containing the executed script. This field could be if the contract is invoked by system. /// - public IVerifiable ScriptContainer { get; } + public IVerifiable? ScriptContainer { get; } /// /// The snapshot used to read or write data. @@ -119,7 +120,7 @@ public partial class ApplicationEngine : ExecutionEngine /// /// The block being persisted. This field could be if the is . /// - public Block PersistingBlock { get; } + public Block? PersistingBlock { get; } /// /// The used by the engine. @@ -148,17 +149,17 @@ public partial class ApplicationEngine : ExecutionEngine /// /// The exception that caused the execution to terminate abnormally. This field could be if no exception is thrown. /// - public Exception FaultException { get; protected set; } + public Exception? FaultException { get; protected set; } /// /// The script hash of the current context. This field could be if no context is loaded to the engine. /// - public UInt160 CurrentScriptHash => CurrentContext?.GetScriptHash(); + public UInt160? CurrentScriptHash => CurrentContext?.GetScriptHash(); /// /// The script hash of the calling contract. This field could be if the current context is the entry context. /// - public virtual UInt160 CallingScriptHash + public virtual UInt160? CallingScriptHash { get { @@ -171,7 +172,7 @@ public virtual UInt160 CallingScriptHash /// /// The script hash of the entry context. This field could be if no context is loaded to the engine. /// - public virtual UInt160 EntryScriptHash => EntryContext?.GetScriptHash(); + public virtual UInt160? EntryScriptHash => EntryContext?.GetScriptHash(); /// /// The notifications sent during the execution. @@ -196,8 +197,8 @@ public virtual UInt160 CallingScriptHash /// The diagnostic to be used by the . /// The jump table to be used by the . protected ApplicationEngine( - TriggerType trigger, IVerifiable container, DataCache snapshotCache, Block persistingBlock, - ProtocolSettings settings, long gas, IDiagnostic diagnostic, JumpTable jumpTable = null) + TriggerType trigger, IVerifiable? container, DataCache snapshotCache, Block? persistingBlock, + ProtocolSettings settings, long gas, IDiagnostic? diagnostic = null, JumpTable? jumpTable = null) : base(jumpTable ?? DefaultJumpTable) { Trigger = trigger; @@ -253,7 +254,7 @@ protected static void OnCallT(ExecutionEngine engine, Instruction instruction) uint tokenId = instruction.TokenU16; app.ValidateCallFlags(CallFlags.ReadStates | CallFlags.AllowCall); - ContractState contract = app.CurrentContext.GetState().Contract; + ContractState? contract = app.CurrentContext!.GetState().Contract; if (contract is null || tokenId >= contract.Nef.Tokens.Length) throw new InvalidOperationException(); MethodToken token = contract.Nef.Tokens[tokenId]; @@ -276,7 +277,7 @@ protected static void OnSysCall(ExecutionEngine engine, Instruction instruction) { var interop = GetInteropDescriptor(instruction.TokenU32); - if (interop?.Hardfork != null && !app.IsHardforkEnabled(interop.Hardfork.Value)) + if (interop.Hardfork != null && !app.IsHardforkEnabled(interop.Hardfork.Value)) { // The syscall is not active @@ -320,9 +321,9 @@ internal void Throw(Exception ex) private ExecutionContext CallContractInternal(UInt160 contractHash, string method, CallFlags flags, bool hasReturnValue, StackItem[] args) { - ContractState contract = NativeContract.ContractManagement.GetContract(SnapshotCache, contractHash); + ContractState? contract = NativeContract.ContractManagement.GetContract(SnapshotCache, contractHash); if (contract is null) throw new InvalidOperationException($"Called Contract Does Not Exist: {contractHash}"); - ContractMethodDescriptor md = contract.Manifest.Abi.GetMethod(method, args.Length); + ContractMethodDescriptor? md = contract.Manifest.Abi.GetMethod(method, args.Length); if (md is null) throw new InvalidOperationException($"Method \"{method}\" with {args.Length} parameter(s) doesn't exist in the contract {contractHash}."); return CallContractInternal(contract, md, flags, hasReturnValue, args); } @@ -332,7 +333,7 @@ private ExecutionContext CallContractInternal(ContractState contract, ContractMe if (NativeContract.Policy.IsBlocked(SnapshotCache, contract.Hash)) throw new InvalidOperationException($"The contract {contract.Hash} has been blocked."); - ExecutionContext currentContext = CurrentContext; + ExecutionContext currentContext = CurrentContext!; ExecutionContextState state = currentContext.GetState(); if (method.Safe) { @@ -342,7 +343,7 @@ private ExecutionContext CallContractInternal(ContractState contract, ContractMe { var executingContract = IsHardforkEnabled(Hardfork.HF_Domovoi) ? state.Contract // use executing contract state to avoid possible contract update/destroy side-effects, ref. https://github.com/neo-project/neo/pull/3290. - : NativeContract.ContractManagement.GetContract(SnapshotCache, CurrentScriptHash); + : NativeContract.ContractManagement.GetContract(SnapshotCache, CurrentScriptHash!); if (executingContract?.CanCall(contract, method.Name) == false) throw new InvalidOperationException($"Cannot Call Method {method.Name} Of Contract {contract.Hash} From Contract {CurrentScriptHash}"); } @@ -416,7 +417,7 @@ protected override void ContextUnloaded(ExecutionContext context) else { if (state.NotificationCount > 0) - notifications.RemoveRange(notifications.Count - state.NotificationCount, state.NotificationCount); + notifications!.RemoveRange(notifications.Count - state.NotificationCount, state.NotificationCount); } } Diagnostic?.ContextUnloaded(context); @@ -446,13 +447,12 @@ protected override void ContextUnloaded(ExecutionContext context) /// /// The diagnostic to be used by the . /// The engine instance created. - public static ApplicationEngine Create(TriggerType trigger, IVerifiable container, DataCache snapshot, Block persistingBlock = null, ProtocolSettings settings = null, long gas = TestModeGas, IDiagnostic diagnostic = null) + public static ApplicationEngine Create(TriggerType trigger, IVerifiable? container, DataCache snapshot, Block? persistingBlock = null, ProtocolSettings? settings = null, long gas = TestModeGas, IDiagnostic? diagnostic = null) { - var index = persistingBlock?.Index ?? (snapshot == null ? 0 : NativeContract.Ledger.CurrentIndex(snapshot)); - + var index = persistingBlock?.Index ?? NativeContract.Ledger.CurrentIndex(snapshot); + settings ??= ProtocolSettings.Default; // Adjust jump table according persistingBlock - - var jumpTable = settings == null || settings.IsHardforkEnabled(Hardfork.HF_Echidna, index) ? DefaultJumpTable : NotEchidnaJumpTable; + var jumpTable = settings.IsHardforkEnabled(Hardfork.HF_Echidna, index) ? DefaultJumpTable : NotEchidnaJumpTable; var engine = Provider?.Create(trigger, container, snapshot, persistingBlock, settings, gas, diagnostic, jumpTable) ?? new ApplicationEngine(trigger, container, snapshot, persistingBlock, settings, gas, diagnostic, jumpTable); @@ -524,7 +524,7 @@ public ExecutionContext LoadContract(ContractState contract, ContractMethodDescr // Call initialization var init = contract.Manifest.Abi.GetMethod(ContractBasicMethod.Initialize, ContractBasicMethod.InitializePCount); - if (init != null) + if (init is not null) { LoadContext(context.Clone(init.Offset)); } @@ -540,7 +540,7 @@ public ExecutionContext LoadContract(ContractState contract, ContractMethodDescr /// The initial position of the instruction pointer. /// The action used to configure the state of the loaded context. /// The loaded context. - public ExecutionContext LoadScript(Script script, int rvcount = -1, int initialPosition = 0, Action configureState = null) + public ExecutionContext LoadScript(Script script, int rvcount = -1, int initialPosition = 0, Action? configureState = null) { // Create and configure context ExecutionContext context = CreateContext(script, rvcount, initialPosition); @@ -558,7 +558,7 @@ public ExecutionContext LoadScript(Script script, int rvcount = -1, int initialP /// /// The to convert. /// The converted . - protected internal StackItem Convert(object value) + protected internal StackItem Convert(object? value) { if (value is IDisposable disposable) Disposables.Add(disposable); return value switch @@ -594,7 +594,7 @@ protected internal StackItem Convert(object value) /// The to convert. /// The descriptor of the parameter. /// The converted . - protected internal object Convert(StackItem item, InteropParameterDescriptor descriptor) + protected internal object? Convert(StackItem item, InteropParameterDescriptor descriptor) { descriptor.Validate(item); if (descriptor.IsArray) @@ -602,7 +602,7 @@ protected internal object Convert(StackItem item, InteropParameterDescriptor des Array av; if (item is VMArray array) { - av = Array.CreateInstance(descriptor.Type.GetElementType(), array.Count); + av = Array.CreateInstance(descriptor.Type.GetElementType()!, array.Count); for (int i = 0; i < av.Length; i++) av.SetValue(descriptor.Converter(array[i]), i); } @@ -610,7 +610,7 @@ protected internal object Convert(StackItem item, InteropParameterDescriptor des { int count = (int)item.GetInteger(); if (count > Limits.MaxStackSize) throw new InvalidOperationException(); - av = Array.CreateInstance(descriptor.Type.GetElementType(), count); + av = Array.CreateInstance(descriptor.Type.GetElementType()!, count); for (int i = 0; i < av.Length; i++) av.SetValue(descriptor.Converter(Pop()), i); } @@ -618,11 +618,11 @@ protected internal object Convert(StackItem item, InteropParameterDescriptor des } else { - object value = descriptor.Converter(item); + object? value = descriptor.Converter(item); if (descriptor.IsEnum) - value = Enum.ToObject(descriptor.Type, value); + value = Enum.ToObject(descriptor.Type, value!); else if (descriptor.IsInterface) - value = ((InteropInterface)value).GetInterface(); + value = ((InteropInterface?)value)?.GetInterface(); return value; } } @@ -645,7 +645,7 @@ public override void Dispose() /// The requirements to check. internal protected void ValidateCallFlags(CallFlags requiredCallFlags) { - ExecutionContextState state = CurrentContext.GetState(); + ExecutionContextState state = CurrentContext!.GetState(); if (!state.CallFlags.HasFlag(requiredCallFlags)) throw new InvalidOperationException($"Cannot call this SYSCALL with the flag {state.CallFlags}."); } @@ -659,11 +659,11 @@ protected virtual void OnSysCall(InteropDescriptor descriptor) ValidateCallFlags(descriptor.RequiredCallFlags); AddFee(descriptor.FixedPrice * ExecFeeFactor); - object[] parameters = new object[descriptor.Parameters.Count]; + object?[] parameters = new object?[descriptor.Parameters.Count]; for (int i = 0; i < parameters.Length; i++) parameters[i] = Convert(Pop(), descriptor.Parameters[i]); - object returnValue = descriptor.Handler.Invoke(this, parameters); + object? returnValue = descriptor.Handler.Invoke(this, parameters); if (descriptor.Handler.ReturnType != typeof(void)) Push(Convert(returnValue)); } @@ -683,7 +683,7 @@ protected override void PostExecuteInstruction(Instruction instruction) private static Block CreateDummyBlock(IReadOnlyStore snapshot, ProtocolSettings settings) { UInt256 hash = NativeContract.Ledger.CurrentHash(snapshot); - Block currentBlock = NativeContract.Ledger.GetBlock(snapshot, hash); + Block currentBlock = NativeContract.Ledger.GetBlock(snapshot, hash)!; return new Block { Header = new Header @@ -704,7 +704,8 @@ protected static InteropDescriptor Register(string name, string handler, long fi { var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static; var method = typeof(ApplicationEngine).GetMethod(handler, flags) - ?? typeof(ApplicationEngine).GetProperty(handler, flags).GetMethod; + ?? typeof(ApplicationEngine).GetProperty(handler, flags)?.GetMethod + ?? throw new ArgumentException($"Handler {handler} is not found.", nameof(handler)); var descriptor = new InteropDescriptor() { Name = name, @@ -726,7 +727,7 @@ protected static InteropDescriptor Register(string name, string handler, long fi [MethodImpl(MethodImplOptions.AggressiveInlining)] public static InteropDescriptor GetInteropDescriptor(uint methodHash) { - return services[methodHash]; + return services![methodHash]; } /// @@ -741,7 +742,7 @@ public static InteropDescriptor GetInteropDescriptor(uint methodHash) /// The maximum gas, in the unit of datoshi, used in this execution. The execution will fail when the gas is exhausted. /// The diagnostic to be used by the . /// The engine instance created. - public static ApplicationEngine Run(ReadOnlyMemory script, DataCache snapshot, IVerifiable container = null, Block persistingBlock = null, ProtocolSettings settings = null, int offset = 0, long gas = TestModeGas, IDiagnostic diagnostic = null) + public static ApplicationEngine Run(ReadOnlyMemory script, DataCache snapshot, IVerifiable? container = null, Block? persistingBlock = null, ProtocolSettings? settings = null, int offset = 0, long gas = TestModeGas, IDiagnostic? diagnostic = null) { persistingBlock ??= CreateDummyBlock(snapshot, settings ?? ProtocolSettings.Default); ApplicationEngine engine = Create(TriggerType.Application, container, snapshot, persistingBlock, settings, gas, diagnostic); @@ -750,14 +751,14 @@ public static ApplicationEngine Run(ReadOnlyMemory script, DataCache snaps return engine; } - public T GetState() + public T? GetState() where T : notnull { if (states is null) return default; - if (!states.TryGetValue(typeof(T), out object state)) return default; + if (!states.TryGetValue(typeof(T), out object? state)) return default; return (T)state; } - public T GetState(Func factory) + public T GetState(Func factory) where T : notnull { if (states is null) { @@ -767,7 +768,7 @@ public T GetState(Func factory) } else { - if (!states.TryGetValue(typeof(T), out object state)) + if (!states.TryGetValue(typeof(T), out object? state)) { state = factory(); SetState(state); @@ -776,7 +777,7 @@ public T GetState(Func factory) } } - public void SetState(T state) + public void SetState(T state) where T : notnull { states ??= new Dictionary(); states[typeof(T)] = state; diff --git a/src/Neo/SmartContract/BinarySerializer.cs b/src/Neo/SmartContract/BinarySerializer.cs index cd3ef2692b..767d3d7a21 100644 --- a/src/Neo/SmartContract/BinarySerializer.cs +++ b/src/Neo/SmartContract/BinarySerializer.cs @@ -40,7 +40,7 @@ public ContainerPlaceholder(StackItemType type, int count) ElementCount = count; } - public override bool Equals(StackItem other) => throw new NotSupportedException(); + public override bool Equals(StackItem? other) => throw new NotSupportedException(); public override int GetHashCode() => throw new NotSupportedException(); @@ -54,7 +54,7 @@ public ContainerPlaceholder(StackItemType type, int count) /// The limits for the deserialization. /// The used by the . /// The deserialized . - public static StackItem Deserialize(ReadOnlyMemory data, ExecutionEngineLimits limits, IReferenceCounter referenceCounter = null) + public static StackItem Deserialize(ReadOnlyMemory data, ExecutionEngineLimits limits, IReferenceCounter? referenceCounter = null) { MemoryReader reader = new(data); return Deserialize(ref reader, (uint)Math.Min(data.Length, limits.MaxItemSize), limits.MaxStackSize, referenceCounter); @@ -67,7 +67,7 @@ public static StackItem Deserialize(ReadOnlyMemory data, ExecutionEngineLi /// The limits for the deserialization. /// The used by the . /// The deserialized . - public static StackItem Deserialize(ref MemoryReader reader, ExecutionEngineLimits limits, IReferenceCounter referenceCounter = null) + public static StackItem Deserialize(ref MemoryReader reader, ExecutionEngineLimits limits, IReferenceCounter? referenceCounter = null) { return Deserialize(ref reader, limits.MaxItemSize, limits.MaxStackSize, referenceCounter); } @@ -80,7 +80,7 @@ public static StackItem Deserialize(ref MemoryReader reader, ExecutionEngineLimi /// The max of items to serialize /// The used by the . /// The deserialized . - public static StackItem Deserialize(ref MemoryReader reader, uint maxSize, uint maxItems, IReferenceCounter referenceCounter = null) + public static StackItem Deserialize(ref MemoryReader reader, uint maxSize, uint maxItems, IReferenceCounter? referenceCounter = null) { Stack deserialized = new(); var undeserialized = 1; diff --git a/src/Neo/SmartContract/Contract.cs b/src/Neo/SmartContract/Contract.cs index 47b568dee4..220203ec8d 100644 --- a/src/Neo/SmartContract/Contract.cs +++ b/src/Neo/SmartContract/Contract.cs @@ -25,14 +25,14 @@ public class Contract /// /// The script of the contract. /// - public byte[] Script; + public byte[] Script { get => field ??= []; set; } /// /// The parameters of the contract. /// - public ContractParameterType[] ParameterList; + public ContractParameterType[] ParameterList { get => field ?? []; set; } - private UInt160 _scriptHash; + private UInt160? _scriptHash; /// /// The hash of the contract. /// diff --git a/src/Neo/SmartContract/ContractParameter.cs b/src/Neo/SmartContract/ContractParameter.cs index c4273f4e37..ecbe4e03e7 100644 --- a/src/Neo/SmartContract/ContractParameter.cs +++ b/src/Neo/SmartContract/ContractParameter.cs @@ -33,7 +33,7 @@ public class ContractParameter /// /// The value of the parameter. /// - public object Value; + public object? Value; /// /// Initializes a new instance of the class. @@ -73,21 +73,21 @@ public static ContractParameter FromJson(JObject json) { ContractParameter parameter = new() { - Type = Enum.Parse(json["type"].GetString()) + Type = Enum.Parse(json["type"]!.GetString()) }; if (json["value"] != null) { parameter.Value = parameter.Type switch { - ContractParameterType.Signature or ContractParameterType.ByteArray => Convert.FromBase64String(json["value"].AsString()), - ContractParameterType.Boolean => json["value"].AsBoolean(), - ContractParameterType.Integer => BigInteger.Parse(json["value"].AsString()), - ContractParameterType.Hash160 => UInt160.Parse(json["value"].AsString()), - ContractParameterType.Hash256 => UInt256.Parse(json["value"].AsString()), - ContractParameterType.PublicKey => ECPoint.Parse(json["value"].AsString(), ECCurve.Secp256r1), - ContractParameterType.String => json["value"].AsString(), - ContractParameterType.Array => ((JArray)json["value"]).Select(p => FromJson((JObject)p)).ToList(), - ContractParameterType.Map => ((JArray)json["value"]).Select(p => new KeyValuePair(FromJson((JObject)p["key"]), FromJson((JObject)p["value"]))).ToList(), + ContractParameterType.Signature or ContractParameterType.ByteArray => Convert.FromBase64String(json["value"]!.AsString()), + ContractParameterType.Boolean => json["value"]!.AsBoolean(), + ContractParameterType.Integer => BigInteger.Parse(json["value"]!.AsString()), + ContractParameterType.Hash160 => UInt160.Parse(json["value"]!.AsString()), + ContractParameterType.Hash256 => UInt256.Parse(json["value"]!.AsString()), + ContractParameterType.PublicKey => ECPoint.Parse(json["value"]!.AsString(), ECCurve.Secp256r1), + ContractParameterType.String => json["value"]!.AsString(), + ContractParameterType.Array => ((JArray)json["value"]!).Select(p => FromJson((JObject)p!)).ToList(), + ContractParameterType.Map => ((JArray)json["value"]!).Select(p => new KeyValuePair(FromJson((JObject)p!["key"]!), FromJson((JObject)p["value"]!))).ToList(), _ => throw new ArgumentException($"Parameter type '{parameter.Type}' is not supported.", nameof(json)), }; } @@ -142,7 +142,7 @@ public JObject ToJson() return ToJson(this, null); } - private static JObject ToJson(ContractParameter parameter, HashSet context) + private static JObject ToJson(ContractParameter parameter, HashSet? context) { JObject json = new(); json["type"] = parameter.Type; @@ -192,7 +192,7 @@ public override string ToString() return ToString(this, null); } - private static string ToString(ContractParameter parameter, HashSet context) + private static string ToString(ContractParameter parameter, HashSet? context) { switch (parameter.Value) { @@ -247,7 +247,7 @@ private static string ToString(ContractParameter parameter, HashSet Signatures; @@ -46,12 +46,12 @@ public ContextItem(Contract contract) public ContextItem(JObject json) { - Script = json["script"] is JToken.Null ? null : Convert.FromBase64String(json["script"].AsString()); - Parameters = ((JArray)json["parameters"]).Select(p => ContractParameter.FromJson((JObject)p)).ToArray(); - Signatures = ((JObject)json["signatures"]).Properties.Select(p => new + Script = json["script"] is JToken.Null ? null : Convert.FromBase64String(json["script"]!.AsString()); + Parameters = ((JArray)json["parameters"]!).Select(p => ContractParameter.FromJson((JObject)p!)).ToArray(); + Signatures = ((JObject)json["signatures"]!).Properties.Select(p => new { PublicKey = ECPoint.Parse(p.Key, ECCurve.Secp256r1), - Signature = Convert.FromBase64String(p.Value.AsString()) + Signature = Convert.FromBase64String(p.Value!.AsString()) }).ToDictionary(p => p.PublicKey, p => p.Signature); } @@ -62,7 +62,7 @@ public JObject ToJson() json["parameters"] = new JArray(Parameters.Select(p => p.ToJson())); json["signatures"] = new JObject(); foreach (var signature in Signatures) - json["signatures"][signature.Key.ToString()] = Convert.ToBase64String(signature.Value); + json["signatures"]![signature.Key.ToString()] = Convert.ToBase64String(signature.Value); return json; } } @@ -108,12 +108,10 @@ public bool Completed } } - private UInt160[] _scriptHashes = null; - /// /// Gets the script hashes to be verified for the . /// - public IReadOnlyList ScriptHashes => _scriptHashes ??= Verifiable.GetScriptHashesForVerifying(SnapshotCache); + public IReadOnlyList ScriptHashes => field ??= Verifiable.GetScriptHashesForVerifying(SnapshotCache); /// /// Initializes a new instance of the class. @@ -185,7 +183,7 @@ public bool Add(Contract contract, params object[] parameters) /// public bool AddSignature(Contract contract, ECPoint pubkey, byte[] signature) { - if (IsMultiSigContract(contract.Script, out _, out ECPoint[] points)) + if (IsMultiSigContract(contract.Script, out _, out ECPoint[]? points)) { if (!points.Contains(pubkey)) return false; // the public key not in the multi-signature contract @@ -269,7 +267,7 @@ public bool AddWithScriptHash(UInt160 scriptHash) return false; } - private ContextItem CreateItem(Contract contract) + private ContextItem? CreateItem(Contract contract) { if (ContextItems.TryGetValue(contract.ScriptHash, out var item)) return item; @@ -288,27 +286,27 @@ private ContextItem CreateItem(Contract contract) /// The converted context. public static ContractParametersContext FromJson(JObject json, DataCache snapshot) { - var typeName = json["type"].AsString(); + var typeName = json["type"]!.AsString(); var type = typeof(ContractParametersContext).GetTypeInfo().Assembly.GetType(typeName); if (!typeof(IVerifiable).IsAssignableFrom(type)) throw new FormatException($"json['type']({typeName}) is not an {nameof(IVerifiable)}"); - var verifiable = (IVerifiable)Activator.CreateInstance(type); - var data = Convert.FromBase64String(json["data"].AsString()); + var verifiable = (IVerifiable)Activator.CreateInstance(type)!; + var data = Convert.FromBase64String(json["data"]!.AsString()); var reader = new MemoryReader(data); verifiable.DeserializeUnsigned(ref reader); if (json.ContainsProperty("hash")) { - var hash = json["hash"].GetString(); + var hash = json["hash"]!.GetString(); var h256 = UInt256.Parse(hash); if (h256 != verifiable.Hash) throw new FormatException($"json['hash']({hash}) != {verifiable.Hash}"); } - var context = new ContractParametersContext(snapshot, verifiable, (uint)json["network"].GetInt32()); - foreach (var (key, value) in ((JObject)json["items"]).Properties) + var context = new ContractParametersContext(snapshot, verifiable, (uint)json["network"]!.GetInt32()); + foreach (var (key, value) in ((JObject)json["items"]!).Properties) { - context.ContextItems.Add(UInt160.Parse(key), new ContextItem((JObject)value)); + context.ContextItems.Add(UInt160.Parse(key), new ContextItem((JObject)value!)); } return context; } @@ -319,7 +317,7 @@ public static ContractParametersContext FromJson(JObject json, DataCache snapsho /// The hash of the witness script. /// The specified index. /// The parameter with the specified index, null if the script hash not exists in context. - public ContractParameter GetParameter(UInt160 scriptHash, int index) + public ContractParameter? GetParameter(UInt160 scriptHash, int index) { return GetParameters(scriptHash)?[index]; } @@ -329,7 +327,7 @@ public ContractParameter GetParameter(UInt160 scriptHash, int index) /// /// The hash of the witness script. /// The parameters from the witness script, null if the script hash not exists in context. - public IReadOnlyList GetParameters(UInt160 scriptHash) + public IReadOnlyList? GetParameters(UInt160 scriptHash) { if (!ContextItems.TryGetValue(scriptHash, out var item)) return null; @@ -341,7 +339,7 @@ public IReadOnlyList GetParameters(UInt160 scriptHash) /// /// The hash of the witness script. /// The signatures from the witness script. null if the script hash not exists in context. - public IReadOnlyDictionary GetSignatures(UInt160 scriptHash) + public IReadOnlyDictionary? GetSignatures(UInt160 scriptHash) { if (!ContextItems.TryGetValue(scriptHash, out var item)) return null; @@ -353,7 +351,7 @@ public IReadOnlyDictionary GetSignatures(UInt160 scriptHash) /// /// The hash of the witness script. /// The witness script, null if the script hash not exists in context. - public byte[] GetScript(UInt160 scriptHash) + public byte[]? GetScript(UInt160 scriptHash) { if (!ContextItems.TryGetValue(scriptHash, out var item)) return null; @@ -395,7 +393,7 @@ public Witness[] GetWitnesses() /// The parsed context. public static ContractParametersContext Parse(string value, DataCache snapshot) { - return FromJson((JObject)JToken.Parse(value), snapshot); + return FromJson((JObject)JToken.Parse(value)!, snapshot); } /// @@ -406,7 +404,7 @@ public JObject ToJson() { var json = new JObject() { - ["type"] = Verifiable.GetType().FullName, + ["type"] = Verifiable.GetType().FullName!, ["hash"] = Verifiable.Hash.ToString() }; @@ -420,7 +418,7 @@ public JObject ToJson() json["items"] = new JObject(); foreach (var item in ContextItems) - json["items"][item.Key.ToString()] = item.Value.ToJson(); + json["items"]![item.Key.ToString()] = item.Value.ToJson(); json["network"] = Network; return json; } diff --git a/src/Neo/SmartContract/ContractState.cs b/src/Neo/SmartContract/ContractState.cs index af3eca63c6..7467b4effa 100644 --- a/src/Neo/SmartContract/ContractState.cs +++ b/src/Neo/SmartContract/ContractState.cs @@ -38,17 +38,17 @@ public class ContractState : IInteroperableVerifiable /// /// The hash of the contract. /// - public UInt160 Hash; + public required UInt160 Hash; /// /// The nef of the contract. /// - public NefFile Nef; + public required NefFile Nef; /// /// The manifest of the contract. /// - public ContractManifest Manifest; + public required ContractManifest Manifest; /// /// The script of the contract. @@ -107,7 +107,7 @@ public JObject ToJson() }; } - public StackItem ToStackItem(IReferenceCounter referenceCounter) + public StackItem ToStackItem(IReferenceCounter? referenceCounter) { return new Array(referenceCounter, [Id, (int)UpdateCounter, Hash.ToArray(), Nef.ToArray(), Manifest.ToStackItem(referenceCounter)]); } diff --git a/src/Neo/SmartContract/ContractTask.cs b/src/Neo/SmartContract/ContractTask.cs index 2f53b73846..ff407faf7d 100644 --- a/src/Neo/SmartContract/ContractTask.cs +++ b/src/Neo/SmartContract/ContractTask.cs @@ -33,7 +33,7 @@ public ContractTask() protected virtual ContractTaskAwaiter CreateAwaiter() => new(); public ContractTaskAwaiter GetAwaiter() => _awaiter; - public virtual object GetResult() => null; + public virtual object? GetResult() => null; } [AsyncMethodBuilder(typeof(ContractTaskMethodBuilder<>))] @@ -51,6 +51,6 @@ static ContractTask() #pragma warning disable CS0108 // Member hides inherited member; missing new keyword public ContractTaskAwaiter GetAwaiter() => (ContractTaskAwaiter)_awaiter; #pragma warning restore CS0108 // Member hides inherited member; missing new keyword - public override object GetResult() => GetAwaiter().GetResult(); + public override object? GetResult() => GetAwaiter().GetResult(); } } diff --git a/src/Neo/SmartContract/ContractTaskAwaiter.cs b/src/Neo/SmartContract/ContractTaskAwaiter.cs index 833397c04f..60210e889e 100644 --- a/src/Neo/SmartContract/ContractTaskAwaiter.cs +++ b/src/Neo/SmartContract/ContractTaskAwaiter.cs @@ -17,8 +17,8 @@ namespace Neo.SmartContract { internal class ContractTaskAwaiter : INotifyCompletion { - private Action _continuation; - private Exception _exception; + private Action? _continuation; + private Exception? _exception; public bool IsCompleted { get; private set; } @@ -52,9 +52,9 @@ protected void RunContinuation() internal class ContractTaskAwaiter : ContractTaskAwaiter { - private T _result; + private T? _result; - public new T GetResult() + public new T? GetResult() { base.GetResult(); return _result; @@ -68,7 +68,7 @@ public void SetResult(T result) public override void SetResult(ApplicationEngine engine) { - SetResult((T)engine.Convert(engine.Pop(), new InteropParameterDescriptor(typeof(T)))); + SetResult((T)engine.Convert(engine.Pop(), new InteropParameterDescriptor(typeof(T)))!); } } } diff --git a/src/Neo/SmartContract/ContractTaskMethodBuilder.cs b/src/Neo/SmartContract/ContractTaskMethodBuilder.cs index 0727f46aca..e6cdf221bd 100644 --- a/src/Neo/SmartContract/ContractTaskMethodBuilder.cs +++ b/src/Neo/SmartContract/ContractTaskMethodBuilder.cs @@ -16,9 +16,7 @@ namespace Neo.SmartContract { sealed class ContractTaskMethodBuilder { - private ContractTask task; - - public ContractTask Task => task ??= new ContractTask(); + public ContractTask Task => field ??= new ContractTask(); public static ContractTaskMethodBuilder Create() => new(); @@ -58,9 +56,7 @@ public void SetStateMachine(IAsyncStateMachine stateMachine) sealed class ContractTaskMethodBuilder { - private ContractTask task; - - public ContractTask Task => task ??= new ContractTask(); + public ContractTask Task => field ??= new ContractTask(); public static ContractTaskMethodBuilder Create() => new(); diff --git a/src/Neo/SmartContract/DeployedContract.cs b/src/Neo/SmartContract/DeployedContract.cs index 35e146c60a..84d8d98ffe 100644 --- a/src/Neo/SmartContract/DeployedContract.cs +++ b/src/Neo/SmartContract/DeployedContract.cs @@ -30,9 +30,8 @@ public DeployedContract(ContractState contract) { ArgumentNullException.ThrowIfNull(contract); - Script = null; ScriptHash = contract.Hash; - ContractMethodDescriptor descriptor = contract.Manifest.Abi.GetMethod(ContractBasicMethod.Verify, ContractBasicMethod.VerifyPCount); + ContractMethodDescriptor? descriptor = contract.Manifest.Abi.GetMethod(ContractBasicMethod.Verify, ContractBasicMethod.VerifyPCount); if (descriptor is null) throw new NotSupportedException("The smart contract haven't got verify method."); ParameterList = descriptor.Parameters.Select(u => u.Type).ToArray(); diff --git a/src/Neo/SmartContract/ExecutionContextState.cs b/src/Neo/SmartContract/ExecutionContextState.cs index 086d7358f6..e5b10adf32 100644 --- a/src/Neo/SmartContract/ExecutionContextState.cs +++ b/src/Neo/SmartContract/ExecutionContextState.cs @@ -23,22 +23,22 @@ public class ExecutionContextState /// /// The script hash of the current context. /// - public UInt160 ScriptHash { get; set; } + public UInt160? ScriptHash { get; set; } /// /// The calling context. /// - public ExecutionContext CallingContext { get; set; } + public ExecutionContext? CallingContext { get; set; } /// /// The script hash of the calling native contract. Used in native contracts only. /// - internal UInt160 NativeCallingScriptHash { get; set; } + internal UInt160? NativeCallingScriptHash { get; set; } /// /// The of the current context. /// - public ContractState Contract { get; set; } + public ContractState? Contract { get; set; } /// /// The of the current context. @@ -46,9 +46,9 @@ public class ExecutionContextState public CallFlags CallFlags { get; set; } = CallFlags.All; [Obsolete("Use SnapshotCache instead")] - public DataCache Snapshot => SnapshotCache; + public DataCache? Snapshot => SnapshotCache; - public DataCache SnapshotCache { get; set; } + public DataCache? SnapshotCache { get; set; } public int NotificationCount { get; set; } diff --git a/src/Neo/SmartContract/Helper.cs b/src/Neo/SmartContract/Helper.cs index bd885ef5d6..1a867b564a 100644 --- a/src/Neo/SmartContract/Helper.cs +++ b/src/Neo/SmartContract/Helper.cs @@ -23,6 +23,7 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; +using System.Runtime.CompilerServices; namespace Neo.SmartContract { @@ -115,7 +116,7 @@ public static UInt160 GetContractHash(UInt160 sender, uint nefCheckSum, string n /// The script hash of the context. public static UInt160 GetScriptHash(this ExecutionContext context) { - return context.GetState().ScriptHash; + return context.GetState().ScriptHash!; } /// @@ -147,7 +148,7 @@ public static bool IsMultiSigContract(ReadOnlySpan script, out int m, out /// The number of correct signatures that need to be provided in order for the verification to pass. /// The public keys in the account. /// if the contract is a multi-signature contract; otherwise, . - public static bool IsMultiSigContract(ReadOnlySpan script, out int m, [NotNullWhen(true)] out ECPoint[] points) + public static bool IsMultiSigContract(ReadOnlySpan script, out int m, [NotNullWhen(true)] out ECPoint[]? points) { List list = new(); if (IsMultiSigContract(script, out m, out _, list)) @@ -162,7 +163,7 @@ public static bool IsMultiSigContract(ReadOnlySpan script, out int m, [Not } } - private static bool IsMultiSigContract(ReadOnlySpan script, out int m, out int n, List points) + private static bool IsMultiSigContract(ReadOnlySpan script, out int m, out int n, List? points) { m = 0; n = 0; int i = 0; @@ -257,9 +258,9 @@ public static bool IsStandardContract(ReadOnlySpan script) /// The type of the . /// The to convert. /// The converted . - public static T ToInteroperable(this StackItem item) where T : IInteroperable, new() + public static T ToInteroperable(this StackItem item) where T : IInteroperable { - T t = new(); + T t = (T)RuntimeHelpers.GetUninitializedObject(typeof(T)); t.FromStackItem(item); return t; } @@ -329,13 +330,14 @@ internal static bool VerifyWitness(this IVerifiable verifiable, ProtocolSettings { return false; } - using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, verifiable, snapshot?.CloneCache(), null, settings, datoshi)) + using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, verifiable, snapshot.CloneCache(), null, settings, datoshi)) { if (witness.VerificationScript.Length == 0) { - ContractState cs = NativeContract.ContractManagement.GetContract(snapshot, hash); + if (snapshot is null) throw new ArgumentNullException(nameof(snapshot), "Snapshot cannot be null when verification script is empty."); + ContractState? cs = NativeContract.ContractManagement.GetContract(snapshot, hash); if (cs is null) return false; - ContractMethodDescriptor md = cs.Manifest.Abi.GetMethod(ContractBasicMethod.Verify, ContractBasicMethod.VerifyPCount); + ContractMethodDescriptor? md = cs.Manifest.Abi.GetMethod(ContractBasicMethod.Verify, ContractBasicMethod.VerifyPCount); if (md?.ReturnType != ContractParameterType.Boolean) return false; engine.LoadContract(cs, md, CallFlags.ReadOnly); } diff --git a/src/Neo/SmartContract/IApplicationEngineProvider.cs b/src/Neo/SmartContract/IApplicationEngineProvider.cs index a2c287adc2..8c614349a3 100644 --- a/src/Neo/SmartContract/IApplicationEngineProvider.cs +++ b/src/Neo/SmartContract/IApplicationEngineProvider.cs @@ -32,6 +32,6 @@ public interface IApplicationEngineProvider /// The diagnostic to be used by the . /// The jump table to be used by the . /// The engine instance created. - ApplicationEngine Create(TriggerType trigger, IVerifiable container, DataCache snapshot, Block persistingBlock, ProtocolSettings settings, long gas, IDiagnostic diagnostic, JumpTable jumpTable); + ApplicationEngine Create(TriggerType trigger, IVerifiable? container, DataCache snapshot, Block? persistingBlock, ProtocolSettings settings, long gas, IDiagnostic? diagnostic, JumpTable jumpTable); } } diff --git a/src/Neo/SmartContract/IInteroperable.cs b/src/Neo/SmartContract/IInteroperable.cs index f2a14addaa..93434f95cf 100644 --- a/src/Neo/SmartContract/IInteroperable.cs +++ b/src/Neo/SmartContract/IInteroperable.cs @@ -31,11 +31,11 @@ public interface IInteroperable /// /// The used by the . /// The converted . - StackItem ToStackItem(IReferenceCounter referenceCounter); + StackItem ToStackItem(IReferenceCounter? referenceCounter); public IInteroperable Clone() { - var result = (IInteroperable)Activator.CreateInstance(GetType()); + var result = (IInteroperable)Activator.CreateInstance(GetType())!; result.FromStackItem(ToStackItem(null)); return result; } diff --git a/src/Neo/SmartContract/InteropDescriptor.cs b/src/Neo/SmartContract/InteropDescriptor.cs index 172dcfda12..46a800bc9a 100644 --- a/src/Neo/SmartContract/InteropDescriptor.cs +++ b/src/Neo/SmartContract/InteropDescriptor.cs @@ -26,7 +26,7 @@ public record InteropDescriptor /// /// The name of the interoperable service. /// - public string Name { get; init; } + public required string Name { get; init; } private uint _hash; /// @@ -45,13 +45,12 @@ public uint Hash /// /// The used to handle the interoperable service. /// - public MethodInfo Handler { get; init; } + public required MethodInfo Handler { get; init; } - private IReadOnlyList _parameters; /// /// The parameters of the interoperable service. /// - public IReadOnlyList Parameters => _parameters ??= Handler.GetParameters().Select(p => new InteropParameterDescriptor(p)).ToList().AsReadOnly(); + public IReadOnlyList Parameters => field ??= Handler.GetParameters().Select(p => new InteropParameterDescriptor(p)).ToList().AsReadOnly(); /// /// The fixed price for calling the interoperable service. It can be 0 if the interoperable service has a variable price. diff --git a/src/Neo/SmartContract/InteropParameterDescriptor.cs b/src/Neo/SmartContract/InteropParameterDescriptor.cs index 6b201e2901..c5627ce902 100644 --- a/src/Neo/SmartContract/InteropParameterDescriptor.cs +++ b/src/Neo/SmartContract/InteropParameterDescriptor.cs @@ -31,7 +31,7 @@ public class InteropParameterDescriptor /// /// The name of the parameter. /// - public string Name { get; } + public string? Name { get; } /// /// The type of the parameter. @@ -41,7 +41,7 @@ public class InteropParameterDescriptor /// /// The converter to convert the parameter from to . /// - public Func Converter { get; } + public Func Converter { get; } /// /// Indicates whether the parameter is an enumeration. @@ -58,7 +58,7 @@ public class InteropParameterDescriptor /// public bool IsInterface { get; } - private static readonly Dictionary> converters = new() + private static readonly Dictionary> converters = new() { [typeof(StackItem)] = p => p, [typeof(Pointer)] = p => p, @@ -97,15 +97,17 @@ internal InteropParameterDescriptor(Type type, params ValidatorAttribute[] valid } else if (IsArray) { - Converter = converters[type.GetElementType()]; + Converter = converters[type.GetElementType()!]; + } + else if (converters.TryGetValue(type, out var converter)) + { + IsInterface = false; + Converter = converter; } else { - IsInterface = !converters.TryGetValue(type, out var converter); - if (IsInterface) - Converter = converters[typeof(InteropInterface)]; - else - Converter = converter; + IsInterface = true; + Converter = converters[typeof(InteropInterface)]; } } diff --git a/src/Neo/SmartContract/Iterators/IIterator.cs b/src/Neo/SmartContract/Iterators/IIterator.cs index dd890146db..73bdb8b4ee 100644 --- a/src/Neo/SmartContract/Iterators/IIterator.cs +++ b/src/Neo/SmartContract/Iterators/IIterator.cs @@ -30,6 +30,6 @@ public interface IIterator : IDisposable /// Gets the element in the collection at the current position of the iterator. /// /// The element in the collection at the current position of the iterator. - StackItem Value(IReferenceCounter referenceCounter); + StackItem Value(IReferenceCounter? referenceCounter); } } diff --git a/src/Neo/SmartContract/Iterators/StorageIterator.cs b/src/Neo/SmartContract/Iterators/StorageIterator.cs index e2e69e7337..5d2db4b6f8 100644 --- a/src/Neo/SmartContract/Iterators/StorageIterator.cs +++ b/src/Neo/SmartContract/Iterators/StorageIterator.cs @@ -40,7 +40,7 @@ public bool Next() return enumerator.MoveNext(); } - public StackItem Value(IReferenceCounter referenceCounter) + public StackItem Value(IReferenceCounter? referenceCounter) { ReadOnlyMemory key = enumerator.Current.Key.Key; ReadOnlyMemory value = enumerator.Current.Value.Value; diff --git a/src/Neo/SmartContract/JsonSerializer.cs b/src/Neo/SmartContract/JsonSerializer.cs index 163131b6f2..0ed80b146a 100644 --- a/src/Neo/SmartContract/JsonSerializer.cs +++ b/src/Neo/SmartContract/JsonSerializer.cs @@ -37,7 +37,7 @@ public static class JsonSerializer /// The to serialize. /// The serialized object. [Obsolete("This method will be removed in the future, do not use.")] - public static JToken Serialize(StackItem item) + public static JToken? Serialize(StackItem item) { switch (item) { @@ -69,7 +69,7 @@ public static JToken Serialize(StackItem item) { if (!(entry.Key is ByteString)) throw new FormatException("Key is not a ByteString"); - var key = entry.Key.GetString(); + var key = entry.Key.GetString()!; var value = Serialize(entry.Value); ret[key] = value; @@ -143,7 +143,7 @@ public static byte[] SerializeToByteArray(StackItem item, uint maxSize) writer.WriteEndObject(); break; case JsonTokenType.PropertyName: - writer.WritePropertyName(((StackItem)stack.Pop()).GetString()); + writer.WritePropertyName(((StackItem)stack.Pop()!).GetString()!); break; case Null _: writer.WriteNullValue(); @@ -166,13 +166,13 @@ public static byte[] SerializeToByteArray(StackItem item, uint maxSize) /// The limits for the deserialization. /// The used by the . /// The deserialized . - public static StackItem Deserialize(ApplicationEngine engine, JToken json, ExecutionEngineLimits limits, IReferenceCounter referenceCounter = null) + public static StackItem Deserialize(ApplicationEngine engine, JToken json, ExecutionEngineLimits limits, IReferenceCounter? referenceCounter = null) { uint maxStackSize = limits.MaxStackSize; return Deserialize(engine, json, ref maxStackSize, referenceCounter); } - private static StackItem Deserialize(ApplicationEngine engine, JToken json, ref uint maxStackSize, IReferenceCounter referenceCounter) + private static StackItem Deserialize(ApplicationEngine engine, JToken? json, ref uint maxStackSize, IReferenceCounter? referenceCounter) { if (maxStackSize-- == 0) throw new FormatException("Max stack size reached"); switch (json) @@ -184,7 +184,7 @@ private static StackItem Deserialize(ApplicationEngine engine, JToken json, ref case JArray array: { List list = new(array.Count); - foreach (JToken obj in array) + foreach (JToken? obj in array) list.Add(Deserialize(engine, obj, ref maxStackSize, referenceCounter)); return new Array(referenceCounter, list); } diff --git a/src/Neo/SmartContract/KeyBuilder.cs b/src/Neo/SmartContract/KeyBuilder.cs index 201a485896..aa04a92bed 100644 --- a/src/Neo/SmartContract/KeyBuilder.cs +++ b/src/Neo/SmartContract/KeyBuilder.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - using Neo.IO; using System; using System.Buffers.Binary; @@ -164,5 +162,3 @@ public static implicit operator StorageKey(KeyBuilder builder) => new(builder.ToArray()); } } - -#nullable disable diff --git a/src/Neo/SmartContract/LogEventArgs.cs b/src/Neo/SmartContract/LogEventArgs.cs index c7e2622fe0..122e1b09d6 100644 --- a/src/Neo/SmartContract/LogEventArgs.cs +++ b/src/Neo/SmartContract/LogEventArgs.cs @@ -22,7 +22,7 @@ public class LogEventArgs : EventArgs /// /// The container that containing the executed script. /// - public IVerifiable ScriptContainer { get; } + public IVerifiable? ScriptContainer { get; } /// /// The script hash of the contract that sends the log. @@ -40,7 +40,7 @@ public class LogEventArgs : EventArgs /// The container that containing the executed script. /// The script hash of the contract that sends the log. /// The message of the log. - public LogEventArgs(IVerifiable container, UInt160 scriptHash, string message) + public LogEventArgs(IVerifiable? container, UInt160 scriptHash, string message) { ScriptContainer = container; ScriptHash = scriptHash; diff --git a/src/Neo/SmartContract/Manifest/ContractAbi.cs b/src/Neo/SmartContract/Manifest/ContractAbi.cs index 15ae2fabbc..054a972e56 100644 --- a/src/Neo/SmartContract/Manifest/ContractAbi.cs +++ b/src/Neo/SmartContract/Manifest/ContractAbi.cs @@ -25,17 +25,17 @@ namespace Neo.SmartContract.Manifest /// For more details, see NEP-14. public class ContractAbi : IInteroperable { - private IReadOnlyDictionary<(string, int), ContractMethodDescriptor> methodDictionary; + private IReadOnlyDictionary<(string, int), ContractMethodDescriptor>? methodDictionary; /// /// Gets the methods in the ABI. /// - public ContractMethodDescriptor[] Methods { get; set; } + public required ContractMethodDescriptor[] Methods { get; set; } /// /// Gets the events in the ABI. /// - public ContractEventDescriptor[] Events { get; set; } + public required ContractEventDescriptor[] Events { get; set; } void IInteroperable.FromStackItem(StackItem stackItem) { @@ -44,7 +44,7 @@ void IInteroperable.FromStackItem(StackItem stackItem) Events = ((Array)@struct[1]).Select(p => p.ToInteroperable()).ToArray(); } - public StackItem ToStackItem(IReferenceCounter referenceCounter) + public StackItem ToStackItem(IReferenceCounter? referenceCounter) { return new Struct(referenceCounter) { @@ -62,8 +62,8 @@ public static ContractAbi FromJson(JObject json) { ContractAbi abi = new() { - Methods = ((JArray)json!["methods"])?.Select(u => ContractMethodDescriptor.FromJson((JObject)u)).ToArray() ?? [], - Events = ((JArray)json!["events"])?.Select(u => ContractEventDescriptor.FromJson((JObject)u)).ToArray() ?? [] + Methods = ((JArray?)json["methods"])?.Select(u => ContractMethodDescriptor.FromJson((JObject)u!)).ToArray() ?? [], + Events = ((JArray?)json["events"])?.Select(u => ContractEventDescriptor.FromJson((JObject)u!)).ToArray() ?? [] }; if (abi.Methods.Length == 0) throw new FormatException("Methods in ContractAbi is empty"); return abi; @@ -81,7 +81,7 @@ public static ContractAbi FromJson(JObject json) /// The method that matches the specified name and number of parameters. /// If is set to -1, the first method with the specified name will be returned. /// - public ContractMethodDescriptor GetMethod(string name, int pcount) + public ContractMethodDescriptor? GetMethod(string name, int pcount) { if (pcount < -1 || pcount > ushort.MaxValue) throw new ArgumentOutOfRangeException(nameof(pcount), $"`pcount` must be between [-1, {ushort.MaxValue}]"); diff --git a/src/Neo/SmartContract/Manifest/ContractEventDescriptor.cs b/src/Neo/SmartContract/Manifest/ContractEventDescriptor.cs index 3f1c47e00d..b47c6c3759 100644 --- a/src/Neo/SmartContract/Manifest/ContractEventDescriptor.cs +++ b/src/Neo/SmartContract/Manifest/ContractEventDescriptor.cs @@ -27,21 +27,21 @@ public class ContractEventDescriptor : IInteroperable, IEquatable /// The name of the event or method. /// - public string Name { get; set; } + public required string Name { get; set; } /// /// The parameters of the event or method. /// - public ContractParameterDefinition[] Parameters { get; set; } + public required ContractParameterDefinition[] Parameters { get; set; } public virtual void FromStackItem(StackItem stackItem) { Struct @struct = (Struct)stackItem; - Name = @struct[0].GetString(); + Name = @struct[0].GetString()!; Parameters = ((Array)@struct[1]).Select(p => p.ToInteroperable()).ToArray(); } - public virtual StackItem ToStackItem(IReferenceCounter referenceCounter) + public virtual StackItem ToStackItem(IReferenceCounter? referenceCounter) { return new Struct(referenceCounter) { @@ -59,8 +59,8 @@ public static ContractEventDescriptor FromJson(JObject json) { ContractEventDescriptor descriptor = new() { - Name = json["name"].GetString(), - Parameters = ((JArray)json["parameters"]).Select(u => ContractParameterDefinition.FromJson((JObject)u)).ToArray(), + Name = json["name"]!.GetString(), + Parameters = ((JArray)json["parameters"]!).Select(u => ContractParameterDefinition.FromJson((JObject)u!)).ToArray(), }; if (string.IsNullOrEmpty(descriptor.Name)) throw new FormatException("Name in ContractEventDescriptor is empty"); _ = descriptor.Parameters.ToDictionary(p => p.Name); @@ -80,15 +80,15 @@ public virtual JObject ToJson() }; } - public bool Equals(ContractEventDescriptor other) + public bool Equals(ContractEventDescriptor? other) { - if (other == null) return false; + if (other is null) return false; if (ReferenceEquals(this, other)) return true; return Name == other.Name && Parameters.SequenceEqual(other.Parameters); } - public override bool Equals(object other) + public override bool Equals(object? other) { if (other is not ContractEventDescriptor ev) return false; diff --git a/src/Neo/SmartContract/Manifest/ContractGroup.cs b/src/Neo/SmartContract/Manifest/ContractGroup.cs index 4b4873d053..6ddc3dc605 100644 --- a/src/Neo/SmartContract/Manifest/ContractGroup.cs +++ b/src/Neo/SmartContract/Manifest/ContractGroup.cs @@ -29,12 +29,12 @@ public class ContractGroup : IInteroperable /// /// The public key of the group. /// - public ECPoint PubKey { get; set; } + public required ECPoint PubKey { get; set; } /// /// The signature of the contract hash which can be verified by . /// - public byte[] Signature { get; set; } + public required byte[] Signature { get; set; } void IInteroperable.FromStackItem(StackItem stackItem) { @@ -43,7 +43,7 @@ void IInteroperable.FromStackItem(StackItem stackItem) Signature = @struct[1].GetSpan().ToArray(); } - public StackItem ToStackItem(IReferenceCounter referenceCounter) + public StackItem ToStackItem(IReferenceCounter? referenceCounter) { return new Struct(referenceCounter) { PubKey.ToArray(), Signature }; } @@ -57,8 +57,8 @@ public static ContractGroup FromJson(JObject json) { ContractGroup group = new() { - PubKey = ECPoint.Parse(json["pubkey"].GetString(), ECCurve.Secp256r1), - Signature = Convert.FromBase64String(json["signature"].GetString()), + PubKey = ECPoint.Parse(json["pubkey"]!.GetString(), ECCurve.Secp256r1), + Signature = Convert.FromBase64String(json["signature"]!.GetString()), }; if (group.Signature.Length != 64) throw new FormatException($"Signature length({group.Signature.Length}) is not 64"); diff --git a/src/Neo/SmartContract/Manifest/ContractManifest.cs b/src/Neo/SmartContract/Manifest/ContractManifest.cs index 6643ab93af..0de0d0b750 100644 --- a/src/Neo/SmartContract/Manifest/ContractManifest.cs +++ b/src/Neo/SmartContract/Manifest/ContractManifest.cs @@ -35,48 +35,48 @@ public class ContractManifest : IInteroperable /// /// The name of the contract. /// - public string Name { get; set; } + public required string Name { get; set; } /// /// The groups of the contract. /// - public ContractGroup[] Groups { get; set; } + public required ContractGroup[] Groups { get; set; } /// /// Indicates which standards the contract supports. It can be a list of NEPs. /// - public string[] SupportedStandards { get; set; } + public required string[] SupportedStandards { get; set; } /// /// The ABI of the contract. /// - public ContractAbi Abi { get; set; } + public required ContractAbi Abi { get; set; } /// /// The permissions of the contract. /// - public ContractPermission[] Permissions { get; set; } + public required ContractPermission[] Permissions { get; set; } /// /// The trusted contracts and groups of the contract. /// If a contract is trusted, the user interface will not give any warnings when called by the contract. /// - public WildcardContainer Trusts { get; set; } + public required WildcardContainer Trusts { get; set; } /// /// Custom user data. /// - public JObject Extra { get; set; } + public JObject? Extra { get; set; } void IInteroperable.FromStackItem(StackItem stackItem) { Struct @struct = (Struct)stackItem; - Name = @struct[0].GetString(); + Name = @struct[0].GetString()!; Groups = ((Array)@struct[1]).Select(p => p.ToInteroperable()).ToArray(); if (((Map)@struct[2]).Count != 0) throw new ArgumentException("Features field must be empty", nameof(stackItem)); - SupportedStandards = ((Array)@struct[3]).Select(p => p.GetString()).ToArray(); + SupportedStandards = ((Array)@struct[3]).Select(p => p.GetString()!).ToArray(); Abi = @struct[4].ToInteroperable(); Permissions = ((Array)@struct[5]).Select(p => p.ToInteroperable()).ToArray(); Trusts = @struct[6] switch @@ -86,10 +86,10 @@ void IInteroperable.FromStackItem(StackItem stackItem) Array array => WildcardContainer.Create(array.Select(ContractPermissionDescriptor.Create).ToArray()), _ => throw new ArgumentException("Trusts field must be null or array", nameof(stackItem)) }; - Extra = (JObject)JToken.Parse(@struct[7].GetSpan()); + Extra = (JObject?)JToken.Parse(@struct[7].GetSpan()); } - public StackItem ToStackItem(IReferenceCounter referenceCounter) + public StackItem ToStackItem(IReferenceCounter? referenceCounter) { return new Struct(referenceCounter) { @@ -114,12 +114,12 @@ public static ContractManifest FromJson(JObject json) ContractManifest manifest = new() { Name = json["name"]!.GetString(), - Groups = ((JArray)json["groups"])?.Select(u => ContractGroup.FromJson((JObject)u)).ToArray() ?? [], - SupportedStandards = ((JArray)json["supportedstandards"])?.Select(u => u.GetString()).ToArray() ?? [], - Abi = ContractAbi.FromJson((JObject)json["abi"]), - Permissions = ((JArray)json["permissions"])?.Select(u => ContractPermission.FromJson((JObject)u)).ToArray() ?? [], - Trusts = WildcardContainer.FromJson(json["trusts"], u => ContractPermissionDescriptor.FromJson((JString)u)), - Extra = (JObject)json["extra"] + Groups = ((JArray?)json["groups"])?.Select(u => ContractGroup.FromJson((JObject)u!)).ToArray() ?? [], + SupportedStandards = ((JArray?)json["supportedstandards"])?.Select(u => u!.GetString()).ToArray() ?? [], + Abi = ContractAbi.FromJson((JObject)json["abi"]!), + Permissions = ((JArray?)json["permissions"])?.Select(u => ContractPermission.FromJson((JObject)u!)).ToArray() ?? [], + Trusts = WildcardContainer.FromJson(json["trusts"]!, u => ContractPermissionDescriptor.FromJson((JString)u)), + Extra = (JObject?)json["extra"] }; if (string.IsNullOrEmpty(manifest.Name)) @@ -144,7 +144,7 @@ public static ContractManifest Parse(ReadOnlySpan json) { if (json.Length > MaxLength) throw new ArgumentException($"JSON content length {json.Length} exceeds maximum allowed size of {MaxLength} bytes", nameof(json)); - return FromJson((JObject)JToken.Parse(json)); + return FromJson((JObject)JToken.Parse(json)!); } /// diff --git a/src/Neo/SmartContract/Manifest/ContractMethodDescriptor.cs b/src/Neo/SmartContract/Manifest/ContractMethodDescriptor.cs index aa02d07c9c..5bf3ed1b19 100644 --- a/src/Neo/SmartContract/Manifest/ContractMethodDescriptor.cs +++ b/src/Neo/SmartContract/Manifest/ContractMethodDescriptor.cs @@ -48,7 +48,7 @@ public override void FromStackItem(StackItem stackItem) Safe = @struct[4].GetBoolean(); } - public override StackItem ToStackItem(IReferenceCounter referenceCounter) + public override StackItem ToStackItem(IReferenceCounter? referenceCounter) { Struct @struct = (Struct)base.ToStackItem(referenceCounter); @struct.Add((byte)ReturnType); @@ -66,11 +66,11 @@ public override StackItem ToStackItem(IReferenceCounter referenceCounter) { ContractMethodDescriptor descriptor = new() { - Name = json["name"].GetString(), - Parameters = ((JArray)json["parameters"]).Select(u => ContractParameterDefinition.FromJson((JObject)u)).ToArray(), - ReturnType = Enum.Parse(json["returntype"].GetString()), - Offset = json["offset"].GetInt32(), - Safe = json["safe"].GetBoolean() + Name = json["name"]!.GetString(), + Parameters = ((JArray)json["parameters"]!).Select(u => ContractParameterDefinition.FromJson((JObject)u!)).ToArray(), + ReturnType = Enum.Parse(json["returntype"]!.GetString()), + Offset = json["offset"]!.GetInt32(), + Safe = json["safe"]!.GetBoolean() }; if (string.IsNullOrEmpty(descriptor.Name)) @@ -98,7 +98,7 @@ public override JObject ToJson() return json; } - public bool Equals(ContractMethodDescriptor other) + public bool Equals(ContractMethodDescriptor? other) { if (ReferenceEquals(this, other)) return true; @@ -109,7 +109,7 @@ public bool Equals(ContractMethodDescriptor other) && Safe == other.Safe; } - public override bool Equals(object other) + public override bool Equals(object? other) { if (other is not ContractMethodDescriptor ev) return false; diff --git a/src/Neo/SmartContract/Manifest/ContractParameterDefinition.cs b/src/Neo/SmartContract/Manifest/ContractParameterDefinition.cs index 32d02b0423..e90fd0ca02 100644 --- a/src/Neo/SmartContract/Manifest/ContractParameterDefinition.cs +++ b/src/Neo/SmartContract/Manifest/ContractParameterDefinition.cs @@ -25,7 +25,7 @@ public class ContractParameterDefinition : IInteroperable, IEquatable /// The name of the parameter. /// - public string Name { get; set; } + public required string Name { get; set; } /// /// The type of the parameter. It can be any value of except . @@ -35,11 +35,11 @@ public class ContractParameterDefinition : IInteroperable, IEquatable(json["type"].GetString()) + Name = json["name"]!.GetString(), + Type = Enum.Parse(json["type"]!.GetString()) }; if (string.IsNullOrEmpty(parameter.Name)) throw new FormatException("Name in ContractParameterDefinition is empty"); @@ -76,15 +76,15 @@ public JObject ToJson() }; } - public bool Equals(ContractParameterDefinition other) + public bool Equals(ContractParameterDefinition? other) { - if (other == null) return false; + if (other is null) return false; if (ReferenceEquals(this, other)) return true; return Name == other.Name && Type == other.Type; } - public override bool Equals(object other) + public override bool Equals(object? other) { if (other is not ContractParameterDefinition parm) return false; diff --git a/src/Neo/SmartContract/Manifest/ContractPermission.cs b/src/Neo/SmartContract/Manifest/ContractPermission.cs index 2affaac028..5cd2ac1e4a 100644 --- a/src/Neo/SmartContract/Manifest/ContractPermission.cs +++ b/src/Neo/SmartContract/Manifest/ContractPermission.cs @@ -34,14 +34,14 @@ public class ContractPermission : IInteroperable /// If it specifies a public key of a group, then any contract in this group /// may be invoked; If it specifies a wildcard *, then any contract may be invoked. /// - public ContractPermissionDescriptor Contract { get; set; } + public required ContractPermissionDescriptor Contract { get; set; } /// /// Indicates which methods to be called. /// It can also be assigned with a wildcard *. If it is a wildcard *, /// then it means that any method can be called. /// - public WildcardContainer Methods { get; set; } + public required WildcardContainer Methods { get; set; } /// /// A default permission that both and fields are set to wildcard *. @@ -63,16 +63,16 @@ void IInteroperable.FromStackItem(StackItem stackItem) Methods = @struct[1] switch { Null => WildcardContainer.CreateWildcard(), - Array array => WildcardContainer.Create(array.Select(p => p.GetString()).ToArray()), + Array array => WildcardContainer.Create(array.Select(p => p.GetString()!).ToArray()), _ => throw new ArgumentException("Methods field must be null or array", nameof(stackItem)) }; } - public StackItem ToStackItem(IReferenceCounter referenceCounter) + public StackItem ToStackItem(IReferenceCounter? referenceCounter) { return new Struct(referenceCounter) { - Contract.IsWildcard ? StackItem.Null : Contract.IsHash ? Contract.Hash.ToArray() : Contract.Group.ToArray(), + Contract.IsWildcard ? StackItem.Null : Contract.IsHash ? Contract.Hash.ToArray() : Contract.Group!.ToArray(), Methods.IsWildcard ? StackItem.Null : new Array(referenceCounter, Methods.Select(p => (StackItem)p)), }; } @@ -86,8 +86,8 @@ public static ContractPermission FromJson(JObject json) { ContractPermission permission = new() { - Contract = ContractPermissionDescriptor.FromJson((JString)json["contract"]), - Methods = WildcardContainer.FromJson(json["methods"], u => u.GetString()), + Contract = ContractPermissionDescriptor.FromJson((JString)json["contract"]!), + Methods = WildcardContainer.FromJson(json["methods"]!, u => u.GetString()), }; if (permission.Methods.Any(p => string.IsNullOrEmpty(p))) throw new FormatException("Methods in ContractPermission has empty string"); diff --git a/src/Neo/SmartContract/Manifest/ContractPermissionDescriptor.cs b/src/Neo/SmartContract/Manifest/ContractPermissionDescriptor.cs index d5f6d36c32..97479be2b2 100644 --- a/src/Neo/SmartContract/Manifest/ContractPermissionDescriptor.cs +++ b/src/Neo/SmartContract/Manifest/ContractPermissionDescriptor.cs @@ -14,6 +14,7 @@ using Neo.Json; using Neo.VM.Types; using System; +using System.Diagnostics.CodeAnalysis; namespace Neo.SmartContract.Manifest { @@ -25,21 +26,23 @@ public class ContractPermissionDescriptor : IEquatable /// The hash of the contract. It can't be set with . /// - public UInt160 Hash { get; } + public UInt160? Hash { get; } /// /// The group of the contracts. It can't be set with . /// - public ECPoint Group { get; } + public ECPoint? Group { get; } /// /// Indicates whether is set. /// + [MemberNotNullWhen(true, nameof(Hash))] public bool IsHash => Hash != null; /// /// Indicates whether is set. /// + [MemberNotNullWhen(true, nameof(Group))] public bool IsGroup => Group != null; /// @@ -47,7 +50,7 @@ public class ContractPermissionDescriptor : IEquatable public bool IsWildcard => Hash is null && Group is null; - private ContractPermissionDescriptor(UInt160 hash, ECPoint group) + private ContractPermissionDescriptor(UInt160? hash, ECPoint? group) { Hash = hash; Group = group; @@ -102,13 +105,13 @@ public static ContractPermissionDescriptor CreateWildcard() return new ContractPermissionDescriptor(null, null); } - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (obj is not ContractPermissionDescriptor other) return false; return Equals(other); } - public bool Equals(ContractPermissionDescriptor other) + public bool Equals(ContractPermissionDescriptor? other) { if (other is null) return false; if (this == other) return true; @@ -155,7 +158,7 @@ public JString ToJson() /// Converts the permission descriptor to byte array. /// /// The converted byte array. Or if it is a wildcard. - public byte[] ToArray() + public byte[]? ToArray() { return Hash?.ToArray() ?? Group?.EncodePoint(true); } diff --git a/src/Neo/SmartContract/Manifest/WildCardContainer.cs b/src/Neo/SmartContract/Manifest/WildCardContainer.cs index 462cbca479..f06bc2549e 100644 --- a/src/Neo/SmartContract/Manifest/WildCardContainer.cs +++ b/src/Neo/SmartContract/Manifest/WildCardContainer.cs @@ -23,9 +23,9 @@ namespace Neo.SmartContract.Manifest /// The type of the elements. public class WildcardContainer : IReadOnlyList { - private readonly T[] _data; + private readonly T[]? _data; - public T this[int index] => _data[index]; + public T this[int index] => _data![index]; public int Count => _data?.Length ?? 0; @@ -34,7 +34,7 @@ public class WildcardContainer : IReadOnlyList /// public bool IsWildcard => _data is null; - private WildcardContainer(T[] data) + private WildcardContainer(T[]? data) { _data = data; } @@ -66,7 +66,7 @@ public static WildcardContainer FromJson(JToken json, Func element if (str.Value != "*") throw new FormatException($"Invalid wildcard('{str.Value}')"); return CreateWildcard(); case JArray array: - return Create(array.Select(p => elementSelector(p)).ToArray()); + return Create(array.Select(p => elementSelector(p!)).ToArray()); default: throw new FormatException($"Invalid json type for wildcard({json.GetType()})"); } @@ -88,7 +88,7 @@ public IEnumerator GetEnumerator() public JToken ToJson(Func elementSelector) { if (IsWildcard) return "*"; - return _data.Select(p => elementSelector(p)).ToArray(); + return _data!.Select(p => elementSelector(p)).ToArray(); } } } diff --git a/src/Neo/SmartContract/MethodToken.cs b/src/Neo/SmartContract/MethodToken.cs index c84c3e4c93..a999390458 100644 --- a/src/Neo/SmartContract/MethodToken.cs +++ b/src/Neo/SmartContract/MethodToken.cs @@ -25,12 +25,12 @@ public class MethodToken : ISerializable /// /// The hash of the contract to be called. /// - public UInt160 Hash; + public required UInt160 Hash; /// /// The name of the method to be called. /// - public string Method; + public required string Method; /// /// The number of parameters of the method to be called. diff --git a/src/Neo/SmartContract/Native/AccountState.cs b/src/Neo/SmartContract/Native/AccountState.cs index a5d27a0f28..4a90465362 100644 --- a/src/Neo/SmartContract/Native/AccountState.cs +++ b/src/Neo/SmartContract/Native/AccountState.cs @@ -30,7 +30,7 @@ public virtual void FromStackItem(StackItem stackItem) Balance = ((Struct)stackItem)[0].GetInteger(); } - public virtual StackItem ToStackItem(IReferenceCounter referenceCounter) + public virtual StackItem ToStackItem(IReferenceCounter? referenceCounter) { return new Struct(referenceCounter) { Balance }; } diff --git a/src/Neo/SmartContract/Native/ContractManagement.cs b/src/Neo/SmartContract/Native/ContractManagement.cs index cf62b3cbf6..d71771189e 100644 --- a/src/Neo/SmartContract/Native/ContractManagement.cs +++ b/src/Neo/SmartContract/Native/ContractManagement.cs @@ -44,7 +44,7 @@ internal ContractManagement() : base() { } private int GetNextAvailableId(DataCache snapshot) { - StorageItem item = snapshot.GetAndChange(CreateStorageKey(Prefix_NextAvailableId)); + StorageItem item = snapshot.GetAndChange(CreateStorageKey(Prefix_NextAvailableId))!; int value = (int)(BigInteger)item; item.Add(1); return value; @@ -62,7 +62,7 @@ internal override ContractTask InitializeAsync(ApplicationEngine engine, Hardfor private async ContractTask OnDeployAsync(ApplicationEngine engine, ContractState contract, StackItem data, bool update) { - ContractMethodDescriptor md = contract.Manifest.Abi.GetMethod(ContractBasicMethod.Deploy, ContractBasicMethod.DeployPCount); + ContractMethodDescriptor? md = contract.Manifest.Abi.GetMethod(ContractBasicMethod.Deploy, ContractBasicMethod.DeployPCount); if (md is not null) await engine.CallFromNativeContractAsync(Hash, contract.Hash, md.Name, data, update); engine.SendNotification(Hash, update ? "Update" : "Deploy", new Array(engine.ReferenceCounter) { contract.Hash.ToArray() }); @@ -72,10 +72,10 @@ internal override async ContractTask OnPersistAsync(ApplicationEngine engine) { foreach (NativeContract contract in Contracts) { - if (contract.IsInitializeBlock(engine.ProtocolSettings, engine.PersistingBlock.Index, out var hfs)) + if (contract.IsInitializeBlock(engine.ProtocolSettings, engine.PersistingBlock!.Index, out var hfs)) { ContractState contractState = contract.GetContractState(engine.ProtocolSettings, engine.PersistingBlock.Index); - StorageItem state = engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_Contract, contract.Hash)); + StorageItem? state = engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_Contract, contract.Hash)); if (state is null) { @@ -141,7 +141,7 @@ private void SetMinimumDeploymentFee(ApplicationEngine engine, BigInteger value/ { if (value < 0) throw new ArgumentOutOfRangeException(nameof(value), "cannot be negative"); AssertCommittee(engine); - engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_MinimumDeploymentFee)).Set(value); + engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_MinimumDeploymentFee))!.Set(value); } /// @@ -151,7 +151,7 @@ private void SetMinimumDeploymentFee(ApplicationEngine engine, BigInteger value/ /// The hash of the deployed contract. /// The deployed contract. [ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.ReadStates)] - public ContractState GetContract(IReadOnlyStore snapshot, UInt160 hash) + public ContractState? GetContract(IReadOnlyStore snapshot, UInt160 hash) { var key = CreateStorageKey(Prefix_Contract, hash); return snapshot.TryGet(key, out var item) ? item.GetInteroperable(false) : null; @@ -177,7 +177,7 @@ public bool IsContract(IReadOnlyStore snapshot, UInt160 hash) /// Contract ID. /// The deployed contract. [ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.ReadStates)] - public ContractState GetContractById(IReadOnlyStore snapshot, int id) + public ContractState? GetContractById(IReadOnlyStore snapshot, int id) { var key = CreateStorageKey(Prefix_ContractHash, id); return snapshot.TryGet(key, out var item) ? GetContract(snapshot, new UInt160(item.Value.Span)) : null; @@ -256,7 +256,7 @@ private async ContractTask Deploy(ApplicationEngine engine, byte[ // Require CallFlags.All flag for post-Aspidochelone transactions, ref. #2653, #2673. if (engine.IsHardforkEnabled(Hardfork.HF_Aspidochelone)) { - var state = engine.CurrentContext.GetState(); + var state = engine.CurrentContext!.GetState(); if (!state.CallFlags.HasFlag(CallFlags.All)) throw new InvalidOperationException($"Cannot call Deploy with the flag {state.CallFlags}."); } @@ -329,7 +329,7 @@ private ContractTask Update(ApplicationEngine engine, byte[] nefFile, byte[] man // Require CallFlags.All flag for post-Aspidochelone transactions, ref. #2653, #2673. if (engine.IsHardforkEnabled(Hardfork.HF_Aspidochelone)) { - var state = engine.CurrentContext.GetState(); + var state = engine.CurrentContext!.GetState(); if (!state.CallFlags.HasFlag(CallFlags.All)) throw new InvalidOperationException($"Cannot call Update with the flag {state.CallFlags}."); } @@ -338,7 +338,7 @@ private ContractTask Update(ApplicationEngine engine, byte[] nefFile, byte[] man engine.AddFee(engine.StoragePrice * ((nefFile?.Length ?? 0) + (manifest?.Length ?? 0))); - var contractState = engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_Contract, engine.CallingScriptHash)) + var contractState = engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_Contract, engine.CallingScriptHash!)) ?? throw new InvalidOperationException($"Updating Contract Does Not Exist: {engine.CallingScriptHash}"); using var sealInterop = contractState.GetInteroperable(out ContractState contract, false); @@ -379,9 +379,9 @@ private ContractTask Update(ApplicationEngine engine, byte[] nefFile, byte[] man [ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.States | CallFlags.AllowNotify)] private void Destroy(ApplicationEngine engine) { - UInt160 hash = engine.CallingScriptHash; + UInt160 hash = engine.CallingScriptHash!; StorageKey ckey = CreateStorageKey(Prefix_Contract, hash); - ContractState contract = engine.SnapshotCache.TryGet(ckey)?.GetInteroperable(false); + ContractState? contract = engine.SnapshotCache.TryGet(ckey)?.GetInteroperable(false); if (contract is null) return; engine.SnapshotCache.Delete(ckey); engine.SnapshotCache.Delete(CreateStorageKey(Prefix_ContractHash, contract.Id)); diff --git a/src/Neo/SmartContract/Native/ContractMethodAttribute.cs b/src/Neo/SmartContract/Native/ContractMethodAttribute.cs index dc829b00e2..7943448311 100644 --- a/src/Neo/SmartContract/Native/ContractMethodAttribute.cs +++ b/src/Neo/SmartContract/Native/ContractMethodAttribute.cs @@ -19,7 +19,7 @@ namespace Neo.SmartContract.Native [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)] internal class ContractMethodAttribute : Attribute, IHardforkActivable { - public string Name { get; init; } + public string? Name { get; init; } public CallFlags RequiredCallFlags { get; init; } public long CpuFee { get; init; } public long StorageFee { get; init; } diff --git a/src/Neo/SmartContract/Native/ContractMethodMetadata.cs b/src/Neo/SmartContract/Native/ContractMethodMetadata.cs index 1efcfb02c9..b995443784 100644 --- a/src/Neo/SmartContract/Native/ContractMethodMetadata.cs +++ b/src/Neo/SmartContract/Native/ContractMethodMetadata.cs @@ -47,7 +47,7 @@ public ContractMethodMetadata(MemberInfo member, ContractMethodAttribute attribu Handler = member switch { MethodInfo m => m, - PropertyInfo p => p.GetMethod, + PropertyInfo p => p.GetMethod ?? throw new ArgumentException("Property must have a get method."), _ => throw new ArgumentException("Member type not supported", nameof(member)) }; ParameterInfo[] parameterInfos = Handler.GetParameters(); @@ -70,7 +70,7 @@ public ContractMethodMetadata(MemberInfo member, ContractMethodAttribute attribu { Name = Name, ReturnType = ToParameterType(Handler.ReturnType), - Parameters = Parameters.Select(p => new ContractParameterDefinition { Type = ToParameterType(p.Type), Name = p.Name }).ToArray(), + Parameters = Parameters.Select(p => new ContractParameterDefinition { Type = ToParameterType(p.Type), Name = p.Name! }).ToArray(), Safe = (attribute.RequiredCallFlags & ~CallFlags.ReadOnly) == 0 }; } diff --git a/src/Neo/SmartContract/Native/CryptoLib.cs b/src/Neo/SmartContract/Native/CryptoLib.cs index 66dfbc138e..24be9e6eda 100644 --- a/src/Neo/SmartContract/Native/CryptoLib.cs +++ b/src/Neo/SmartContract/Native/CryptoLib.cs @@ -40,7 +40,7 @@ internal CryptoLib() : base() { } /// The 65-byte signature in format: r[32] + s[32] + v[1]. 64-bytes for eip-2098, where v must be 27 or 28. /// The recovered public key in compressed format, or null if recovery fails. [ContractMethod(Hardfork.HF_Echidna, CpuFee = 1 << 15, Name = "recoverSecp256K1")] - public static byte[] RecoverSecp256K1(byte[] messageHash, byte[] signature) + public static byte[]? RecoverSecp256K1(byte[] messageHash, byte[] signature) { // It will be checked in Crypto.ECRecover // if (signature.Length != 65 && signature.Length != 64) diff --git a/src/Neo/SmartContract/Native/FungibleToken.cs b/src/Neo/SmartContract/Native/FungibleToken.cs index 3ed5268786..eef81c11d3 100644 --- a/src/Neo/SmartContract/Native/FungibleToken.cs +++ b/src/Neo/SmartContract/Native/FungibleToken.cs @@ -88,7 +88,7 @@ internal async ContractTask Burn(ApplicationEngine engine, UInt160 account, BigI if (amount.Sign < 0) throw new ArgumentOutOfRangeException(nameof(amount), "cannot be negative"); if (amount.IsZero) return; StorageKey key = CreateStorageKey(Prefix_Account, account); - StorageItem storage = engine.SnapshotCache.GetAndChange(key); + StorageItem storage = engine.SnapshotCache.GetAndChange(key)!; TState state = storage.GetInteroperable(); if (state.Balance < amount) throw new InvalidOperationException(); OnBalanceChanging(engine, account, state, -amount); @@ -96,7 +96,7 @@ internal async ContractTask Burn(ApplicationEngine engine, UInt160 account, BigI engine.SnapshotCache.Delete(key); else state.Balance -= amount; - storage = engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_TotalSupply)); + storage = engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_TotalSupply))!; storage.Add(-amount); await PostTransferAsync(engine, account, null, amount, StackItem.Null, false); } @@ -138,7 +138,7 @@ private protected async ContractTask Transfer(ApplicationEngine engine, UI return false; StorageKey keyFrom = CreateStorageKey(Prefix_Account, from); - StorageItem storageFrom = engine.SnapshotCache.GetAndChange(keyFrom); + StorageItem? storageFrom = engine.SnapshotCache.GetAndChange(keyFrom); if (amount.IsZero) { if (storageFrom != null) @@ -178,7 +178,7 @@ internal virtual void OnBalanceChanging(ApplicationEngine engine, UInt160 accoun { } - private protected virtual async ContractTask PostTransferAsync(ApplicationEngine engine, UInt160 from, UInt160 to, BigInteger amount, StackItem data, bool callOnPayment) + private protected virtual async ContractTask PostTransferAsync(ApplicationEngine engine, UInt160? from, UInt160? to, BigInteger amount, StackItem data, bool callOnPayment) { // Send notification diff --git a/src/Neo/SmartContract/Native/GasToken.cs b/src/Neo/SmartContract/Native/GasToken.cs index 9bb790520f..8b4e62da12 100644 --- a/src/Neo/SmartContract/Native/GasToken.cs +++ b/src/Neo/SmartContract/Native/GasToken.cs @@ -39,7 +39,7 @@ internal override ContractTask InitializeAsync(ApplicationEngine engine, Hardfor internal override async ContractTask OnPersistAsync(ApplicationEngine engine) { long totalNetworkFee = 0; - foreach (Transaction tx in engine.PersistingBlock.Transactions) + foreach (Transaction tx in engine.PersistingBlock!.Transactions) { await Burn(engine, tx.Sender, tx.SystemFee + tx.NetworkFee); totalNetworkFee += tx.NetworkFee; diff --git a/src/Neo/SmartContract/Native/HashIndexState.cs b/src/Neo/SmartContract/Native/HashIndexState.cs index 34e2685f9b..e35f8a4bfc 100644 --- a/src/Neo/SmartContract/Native/HashIndexState.cs +++ b/src/Neo/SmartContract/Native/HashIndexState.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - using Neo.Extensions; using Neo.VM; using Neo.VM.Types; @@ -29,11 +27,9 @@ void IInteroperable.FromStackItem(StackItem stackItem) Index = (uint)@struct[1].GetInteger(); } - StackItem IInteroperable.ToStackItem(IReferenceCounter referenceCounter) + StackItem IInteroperable.ToStackItem(IReferenceCounter? referenceCounter) { return new Struct(referenceCounter) { Hash.ToArray(), Index }; } } } - -#nullable disable diff --git a/src/Neo/SmartContract/Native/InteroperableList.cs b/src/Neo/SmartContract/Native/InteroperableList.cs index e9290d6c0b..2327f21fa2 100644 --- a/src/Neo/SmartContract/Native/InteroperableList.cs +++ b/src/Neo/SmartContract/Native/InteroperableList.cs @@ -19,8 +19,7 @@ namespace Neo.SmartContract.Native { abstract class InteroperableList : IList, IInteroperable { - private List list; - private List List => list ??= new(); + private List List => field ??= new(); public T this[int index] { get => List[index]; set => List[index] = value; } public int Count => List.Count; @@ -40,7 +39,7 @@ abstract class InteroperableList : IList, IInteroperable public void Sort() => List.Sort(); protected abstract T ElementFromStackItem(StackItem item); - protected abstract StackItem ElementToStackItem(T element, IReferenceCounter referenceCounter); + protected abstract StackItem ElementToStackItem(T element, IReferenceCounter? referenceCounter); public void FromStackItem(StackItem stackItem) { @@ -51,7 +50,7 @@ public void FromStackItem(StackItem stackItem) } } - public StackItem ToStackItem(IReferenceCounter referenceCounter) + public StackItem ToStackItem(IReferenceCounter? referenceCounter) { return new Array(referenceCounter, this.Select(p => ElementToStackItem(p, referenceCounter))); } diff --git a/src/Neo/SmartContract/Native/LedgerContract.cs b/src/Neo/SmartContract/Native/LedgerContract.cs index b70bd0f28c..c4ea1951d0 100644 --- a/src/Neo/SmartContract/Native/LedgerContract.cs +++ b/src/Neo/SmartContract/Native/LedgerContract.cs @@ -41,7 +41,7 @@ internal LedgerContract() : base() internal override ContractTask OnPersistAsync(ApplicationEngine engine) { - TransactionState[] transactions = engine.PersistingBlock.Transactions.Select(p => new TransactionState + TransactionState[] transactions = engine.PersistingBlock!.Transactions.Select(p => new TransactionState { BlockIndex = engine.PersistingBlock.Index, Transaction = p, @@ -53,7 +53,7 @@ internal override ContractTask OnPersistAsync(ApplicationEngine engine) { // It's possible that there are previously saved malicious conflict records for this transaction. // If so, then remove it and store the relevant transaction itself. - engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_Transaction, tx.Transaction.Hash), () => new StorageItem(new TransactionState())) + engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_Transaction, tx.Transaction!.Hash), () => new StorageItem(new TransactionState())) .FromReplica(new StorageItem(tx)); // Store transaction's conflicits. @@ -79,7 +79,7 @@ internal override ContractTask PostPersistAsync(ApplicationEngine engine) var state = engine.SnapshotCache.GetAndChange(_currentBlock, () => new StorageItem(new HashIndexState())) // Don't need to seal because the size is fixed and it can't grow .GetInteroperable(); - state.Hash = engine.PersistingBlock.Hash; + state.Hash = engine.PersistingBlock!.Hash; state.Index = engine.PersistingBlock.Index; return ContractTask.CompletedTask; } @@ -133,7 +133,7 @@ private bool IsTraceableBlock(IReadOnlyStore snapshot, uint index, uint maxTrace /// The snapshot used to read data. /// The index of the block. /// The hash of the block. - public UInt256 GetBlockHash(IReadOnlyStore snapshot, uint index) + public UInt256? GetBlockHash(IReadOnlyStore snapshot, uint index) { ArgumentNullException.ThrowIfNull(snapshot); @@ -238,7 +238,7 @@ public bool ContainsConflictHash(IReadOnlyStore snapshot, UInt256 hash, IEnumera /// The snapshot used to read data. /// The hash of the block. /// The trimmed block. - public TrimmedBlock GetTrimmedBlock(IReadOnlyStore snapshot, UInt256 hash) + public TrimmedBlock? GetTrimmedBlock(IReadOnlyStore snapshot, UInt256 hash) { ArgumentNullException.ThrowIfNull(snapshot); @@ -249,9 +249,9 @@ public TrimmedBlock GetTrimmedBlock(IReadOnlyStore snapshot, UInt256 hash) } [ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.ReadStates)] - private TrimmedBlock GetBlock(ApplicationEngine engine, byte[] indexOrHash) + private TrimmedBlock? GetBlock(ApplicationEngine engine, byte[] indexOrHash) { - UInt256 hash; + UInt256? hash; if (indexOrHash.Length < UInt256.Length) hash = GetBlockHash(engine.SnapshotCache, (uint)new BigInteger(indexOrHash)); else if (indexOrHash.Length == UInt256.Length) @@ -259,7 +259,7 @@ private TrimmedBlock GetBlock(ApplicationEngine engine, byte[] indexOrHash) else throw new ArgumentException($"Invalid indexOrHash length: {indexOrHash.Length}", nameof(indexOrHash)); if (hash is null) return null; - TrimmedBlock block = GetTrimmedBlock(engine.SnapshotCache, hash); + TrimmedBlock? block = GetTrimmedBlock(engine.SnapshotCache, hash); if (block is null || !IsTraceableBlock(engine, block.Index)) return null; return block; } @@ -270,14 +270,14 @@ private TrimmedBlock GetBlock(ApplicationEngine engine, byte[] indexOrHash) /// The snapshot used to read data. /// The hash of the block. /// The block with the specified hash. - public Block GetBlock(IReadOnlyStore snapshot, UInt256 hash) + public Block? GetBlock(IReadOnlyStore snapshot, UInt256 hash) { - TrimmedBlock state = GetTrimmedBlock(snapshot, hash); + TrimmedBlock? state = GetTrimmedBlock(snapshot, hash); if (state is null) return null; return new Block { Header = state.Header, - Transactions = state.Hashes.Select(p => GetTransaction(snapshot, p)).ToArray() + Transactions = state.Hashes.Select(p => GetTransaction(snapshot, p)!).ToArray() }; } @@ -287,9 +287,9 @@ public Block GetBlock(IReadOnlyStore snapshot, UInt256 hash) /// The snapshot used to read data. /// The index of the block. /// The block with the specified index. - public Block GetBlock(IReadOnlyStore snapshot, uint index) + public Block? GetBlock(IReadOnlyStore snapshot, uint index) { - UInt256 hash = GetBlockHash(snapshot, index); + UInt256? hash = GetBlockHash(snapshot, index); if (hash is null) return null; return GetBlock(snapshot, hash); } @@ -300,7 +300,7 @@ public Block GetBlock(IReadOnlyStore snapshot, uint index) /// The snapshot used to read data. /// The hash of the block. /// The block header with the specified hash. - public Header GetHeader(IReadOnlyStore snapshot, UInt256 hash) + public Header? GetHeader(IReadOnlyStore snapshot, UInt256 hash) { return GetTrimmedBlock(snapshot, hash)?.Header; } @@ -311,9 +311,9 @@ public Header GetHeader(IReadOnlyStore snapshot, UInt256 hash) /// The snapshot used to read data. /// The index of the block. /// The block header with the specified index. - public Header GetHeader(DataCache snapshot, uint index) + public Header? GetHeader(DataCache snapshot, uint index) { - UInt256 hash = GetBlockHash(snapshot, index); + UInt256? hash = GetBlockHash(snapshot, index); if (hash is null) return null; return GetHeader(snapshot, hash); } @@ -324,7 +324,7 @@ public Header GetHeader(DataCache snapshot, uint index) /// The snapshot used to read data. /// The hash of the transaction. /// The with the specified hash. - public TransactionState GetTransactionState(IReadOnlyStore snapshot, UInt256 hash) + public TransactionState? GetTransactionState(IReadOnlyStore snapshot, UInt256 hash) { ArgumentNullException.ThrowIfNull(snapshot); @@ -339,31 +339,31 @@ public TransactionState GetTransactionState(IReadOnlyStore snapshot, UInt256 has /// The snapshot used to read data. /// The hash of the transaction. /// The transaction with the specified hash. - public Transaction GetTransaction(IReadOnlyStore snapshot, UInt256 hash) + public Transaction? GetTransaction(IReadOnlyStore snapshot, UInt256 hash) { return GetTransactionState(snapshot, hash)?.Transaction; } [ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.ReadStates, Name = "getTransaction")] - private Transaction GetTransactionForContract(ApplicationEngine engine, UInt256 hash) + private Transaction? GetTransactionForContract(ApplicationEngine engine, UInt256 hash) { - TransactionState state = GetTransactionState(engine.SnapshotCache, hash); + TransactionState? state = GetTransactionState(engine.SnapshotCache, hash); if (state is null || !IsTraceableBlock(engine, state.BlockIndex)) return null; return state.Transaction; } [ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.ReadStates)] - private Signer[] GetTransactionSigners(ApplicationEngine engine, UInt256 hash) + private Signer[]? GetTransactionSigners(ApplicationEngine engine, UInt256 hash) { - TransactionState state = GetTransactionState(engine.SnapshotCache, hash); + TransactionState? state = GetTransactionState(engine.SnapshotCache, hash); if (state is null || !IsTraceableBlock(engine, state.BlockIndex)) return null; - return state.Transaction.Signers; + return state.Transaction!.Signers; } [ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.ReadStates)] private VMState GetTransactionVMState(ApplicationEngine engine, UInt256 hash) { - TransactionState state = GetTransactionState(engine.SnapshotCache, hash); + TransactionState? state = GetTransactionState(engine.SnapshotCache, hash); if (state is null || !IsTraceableBlock(engine, state.BlockIndex)) return VMState.NONE; return state.State; } @@ -371,15 +371,15 @@ private VMState GetTransactionVMState(ApplicationEngine engine, UInt256 hash) [ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.ReadStates)] private int GetTransactionHeight(ApplicationEngine engine, UInt256 hash) { - TransactionState state = GetTransactionState(engine.SnapshotCache, hash); + TransactionState? state = GetTransactionState(engine.SnapshotCache, hash); if (state is null || !IsTraceableBlock(engine, state.BlockIndex)) return -1; return (int)state.BlockIndex; } [ContractMethod(CpuFee = 1 << 16, RequiredCallFlags = CallFlags.ReadStates)] - private Transaction GetTransactionFromBlock(ApplicationEngine engine, byte[] blockIndexOrHash, int txIndex) + private Transaction? GetTransactionFromBlock(ApplicationEngine engine, byte[] blockIndexOrHash, int txIndex) { - UInt256 hash; + UInt256? hash; if (blockIndexOrHash.Length < UInt256.Length) hash = GetBlockHash(engine.SnapshotCache, (uint)new BigInteger(blockIndexOrHash)); else if (blockIndexOrHash.Length == UInt256.Length) @@ -387,7 +387,7 @@ private Transaction GetTransactionFromBlock(ApplicationEngine engine, byte[] blo else throw new ArgumentException($"Invalid blockIndexOrHash length: {blockIndexOrHash.Length}", nameof(blockIndexOrHash)); if (hash is null) return null; - TrimmedBlock block = GetTrimmedBlock(engine.SnapshotCache, hash); + TrimmedBlock? block = GetTrimmedBlock(engine.SnapshotCache, hash); if (block is null || !IsTraceableBlock(engine, block.Index)) return null; if (txIndex < 0 || txIndex >= block.Hashes.Length) throw new ArgumentOutOfRangeException(nameof(txIndex)); diff --git a/src/Neo/SmartContract/Native/NativeContract.cs b/src/Neo/SmartContract/Native/NativeContract.cs index d6af3b7c19..dc514468a4 100644 --- a/src/Neo/SmartContract/Native/NativeContract.cs +++ b/src/Neo/SmartContract/Native/NativeContract.cs @@ -30,11 +30,7 @@ public abstract class NativeContract { private class NativeContractsCache { - public class CacheEntry - { - public Dictionary Methods { get; set; } - public byte[] Script { get; set; } - } + public record CacheEntry(Dictionary Methods, byte[] Script); internal Dictionary NativeContracts { get; set; } = new(); @@ -157,11 +153,11 @@ protected NativeContract() // Reflection to get the events _eventsDescriptors = - GetType().GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, Array.Empty(), null)?. + GetType().GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, Array.Empty(), null)!. GetCustomAttributes(). // Take into account not only the contract constructor, but also the base type constructor for proper FungibleToken events handling. - Concat(GetType().BaseType?.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, Array.Empty(), null)?. - GetCustomAttributes()). + Concat(GetType().BaseType?.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, Array.Empty(), null)!. + GetCustomAttributes() ?? []). OrderBy(p => p.Order).ToList().AsReadOnly(); // Calculate the initializations forks @@ -171,7 +167,8 @@ protected NativeContract() .Concat(_eventsDescriptors.Select(u => u.DeprecatedIn)) .Concat(_eventsDescriptors.Select(u => u.ActiveIn)) .Concat([ActiveIn]) - .Where(u => u is not null) + .Where(u => u.HasValue) + .Select(u => u!.Value) .OrderBy(u => (byte)u) .Cast().ToImmutableHashSet(); s_contractsList.Add(this); @@ -203,7 +200,7 @@ private NativeContractsCache.CacheEntry GetAllowedMethods(IsHardforkEnabledDeleg script = sb.ToArray(); } - return new NativeContractsCache.CacheEntry { Methods = methods, Script = script }; + return new NativeContractsCache.CacheEntry(methods, script); } /// @@ -286,7 +283,7 @@ protected virtual void OnManifestCompose(IsHardforkEnabledDelegate hfChecker, ui /// Block index /// Active hardforks /// True if the native contract must be initialized - internal bool IsInitializeBlock(ProtocolSettings settings, uint index, [NotNullWhen(true)] out Hardfork[] hardforks) + internal bool IsInitializeBlock(ProtocolSettings settings, uint index, [NotNullWhen(true)] out Hardfork[]? hardforks) { var hfs = new List(); @@ -404,7 +401,7 @@ protected static void AssertCommittee(ApplicationEngine engine) /// /// The hash of the native contract. /// The native contract with the specified hash. - public static NativeContract GetContract(UInt160 hash) + public static NativeContract? GetContract(UInt160 hash) { s_contractsDictionary.TryGetValue(hash, out var contract); return contract; @@ -426,7 +423,7 @@ internal async void Invoke(ApplicationEngine engine, byte version) // Get native contracts invocation cache var currentAllowedMethods = GetContractMethods(engine); // Check if the method is allowed - var context = engine.CurrentContext; + var context = engine.CurrentContext!; var method = currentAllowedMethods[context.InstructionPointer]; if (method.ActiveIn is not null && !engine.IsHardforkEnabled(method.ActiveIn.Value)) throw new InvalidOperationException($"Cannot call this method before hardfork {method.ActiveIn}."); @@ -437,12 +434,12 @@ internal async void Invoke(ApplicationEngine engine, byte version) throw new InvalidOperationException($"Cannot call this method with the flag {state.CallFlags}."); // In the unit of datoshi, 1 datoshi = 1e-8 GAS engine.AddFee(method.CpuFee * engine.ExecFeeFactor + method.StorageFee * engine.StoragePrice); - List parameters = new(); + List parameters = new(); if (method.NeedApplicationEngine) parameters.Add(engine); if (method.NeedSnapshot) parameters.Add(engine.SnapshotCache); for (int i = 0; i < method.Parameters.Length; i++) parameters.Add(engine.Convert(context.EvaluationStack.Peek(i), method.Parameters[i])); - object returnValue = method.Handler.Invoke(this, parameters.ToArray()); + object? returnValue = method.Handler.Invoke(this, parameters.ToArray()); if (returnValue is ContractTask task) { await task; diff --git a/src/Neo/SmartContract/Native/NeoToken.cs b/src/Neo/SmartContract/Native/NeoToken.cs index 2612da731f..f777a9b20d 100644 --- a/src/Neo/SmartContract/Native/NeoToken.cs +++ b/src/Neo/SmartContract/Native/NeoToken.cs @@ -85,25 +85,25 @@ public override BigInteger TotalSupply(IReadOnlyStore snapshot) internal override void OnBalanceChanging(ApplicationEngine engine, UInt160 account, NeoAccountState state, BigInteger amount) { - GasDistribution distribution = DistributeGas(engine, account, state); + GasDistribution? distribution = DistributeGas(engine, account, state); if (distribution is not null) { - var list = engine.CurrentContext.GetState>(); + var list = engine.CurrentContext!.GetState>(); list.Add(distribution); } if (amount.IsZero) return; if (state.VoteTo is null) return; - engine.SnapshotCache.GetAndChange(_votersCount).Add(amount); + engine.SnapshotCache.GetAndChange(_votersCount)!.Add(amount); StorageKey key = CreateStorageKey(Prefix_Candidate, state.VoteTo); - CandidateState candidate = engine.SnapshotCache.GetAndChange(key).GetInteroperable(); + CandidateState candidate = engine.SnapshotCache.GetAndChange(key)!.GetInteroperable(); candidate.Votes += amount; CheckCandidate(engine.SnapshotCache, state.VoteTo, candidate); } - private protected override async ContractTask PostTransferAsync(ApplicationEngine engine, UInt160 from, UInt160 to, BigInteger amount, StackItem data, bool callOnPayment) + private protected override async ContractTask PostTransferAsync(ApplicationEngine engine, UInt160? from, UInt160? to, BigInteger amount, StackItem data, bool callOnPayment) { await base.PostTransferAsync(engine, from, to, amount, data, callOnPayment); - var list = engine.CurrentContext.GetState>(); + var list = engine.CurrentContext!.GetState>(); foreach (var distribution in list) await GAS.Mint(engine, distribution.Account, distribution.Amount, callOnPayment); } @@ -120,7 +120,7 @@ protected override void OnManifestCompose(IsHardforkEnabledDelegate hfChecker, u } } - private GasDistribution DistributeGas(ApplicationEngine engine, UInt160 account, NeoAccountState state) + private GasDistribution? DistributeGas(ApplicationEngine engine, UInt160 account, NeoAccountState state) { // PersistingBlock is null when running under the debugger if (engine.PersistingBlock is null) return null; @@ -215,9 +215,9 @@ internal override ContractTask InitializeAsync(ApplicationEngine engine, Hardfor internal override ContractTask OnPersistAsync(ApplicationEngine engine) { // Set next committee - if (ShouldRefreshCommittee(engine.PersistingBlock.Index, engine.ProtocolSettings.CommitteeMembersCount)) + if (ShouldRefreshCommittee(engine.PersistingBlock!.Index, engine.ProtocolSettings.CommitteeMembersCount)) { - var storageItem = engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_Committee)); + var storageItem = engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_Committee))!; var cachedCommittee = storageItem.GetInteroperable(); var prevCommittee = cachedCommittee.Select(u => u.PublicKey).ToArray(); @@ -249,7 +249,7 @@ internal override async ContractTask PostPersistAsync(ApplicationEngine engine) int m = engine.ProtocolSettings.CommitteeMembersCount; int n = engine.ProtocolSettings.ValidatorsCount; - int index = (int)(engine.PersistingBlock.Index % (uint)m); + int index = (int)(engine.PersistingBlock!.Index % (uint)m); var gasPerBlock = GetGasPerBlock(engine.SnapshotCache); var committee = GetCommitteeFromCache(engine.SnapshotCache); var pubkey = committee[index].PublicKey; @@ -288,7 +288,7 @@ private void SetGasPerBlock(ApplicationEngine engine, BigInteger gasPerBlock) throw new ArgumentOutOfRangeException(nameof(gasPerBlock), $"GasPerBlock must be between [0, {10 * GAS.Factor}]"); AssertCommittee(engine); - var index = engine.PersistingBlock.Index + 1; + var index = engine.PersistingBlock!.Index + 1; var entry = engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_GasPerBlock, index), () => new StorageItem(gasPerBlock)); entry.Set(gasPerBlock); } @@ -316,7 +316,7 @@ private void SetRegisterPrice(ApplicationEngine engine, long registerPrice) throw new ArgumentOutOfRangeException(nameof(registerPrice), "RegisterPrice must be positive"); AssertCommittee(engine); - engine.SnapshotCache.GetAndChange(_registerPrice).Set(registerPrice); + engine.SnapshotCache.GetAndChange(_registerPrice)!.Set(registerPrice); } /// @@ -349,7 +349,7 @@ public long GetRegisterPrice(IReadOnlyStore snapshot) [ContractMethod(CpuFee = 1 << 17, RequiredCallFlags = CallFlags.ReadStates)] public BigInteger UnclaimedGas(DataCache snapshot, UInt160 account, uint end) { - StorageItem storage = snapshot.TryGet(CreateStorageKey(Prefix_Account, account)); + StorageItem? storage = snapshot.TryGet(CreateStorageKey(Prefix_Account, account)); if (storage is null) return BigInteger.Zero; NeoAccountState state = storage.GetInteroperable(); return CalculateBonus(snapshot, state, end); @@ -427,7 +427,7 @@ private bool UnregisterCandidate(ApplicationEngine engine, ECPoint pubkey) return false; StorageKey key = CreateStorageKey(Prefix_Candidate, pubkey); if (engine.SnapshotCache.TryGet(key) is null) return true; - StorageItem item = engine.SnapshotCache.GetAndChange(key); + StorageItem item = engine.SnapshotCache.GetAndChange(key)!; CandidateState state = item.GetInteroperable(); if (!state.Registered) return true; state.Registered = false; @@ -449,11 +449,11 @@ private bool UnregisterCandidate(ApplicationEngine engine, ECPoint pubkey) private async ContractTask Vote(ApplicationEngine engine, UInt160 account, ECPoint voteTo) { if (!engine.CheckWitnessInternal(account)) return false; - NeoAccountState stateAccount = engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_Account, account))?.GetInteroperable(); + NeoAccountState? stateAccount = engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_Account, account))?.GetInteroperable(); if (stateAccount is null) return false; if (stateAccount.Balance == 0) return false; - CandidateState validatorNew = null; + CandidateState? validatorNew = null; if (voteTo != null) { validatorNew = engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_Candidate, voteTo))?.GetInteroperable(); @@ -462,17 +462,17 @@ private async ContractTask Vote(ApplicationEngine engine, UInt160 account, } if (stateAccount.VoteTo is null ^ voteTo is null) { - StorageItem item = engine.SnapshotCache.GetAndChange(_votersCount); + StorageItem item = engine.SnapshotCache.GetAndChange(_votersCount)!; if (stateAccount.VoteTo is null) item.Add(stateAccount.Balance); else item.Add(-stateAccount.Balance); } - GasDistribution gasDistribution = DistributeGas(engine, account, stateAccount); + GasDistribution? gasDistribution = DistributeGas(engine, account, stateAccount); if (stateAccount.VoteTo != null) { StorageKey key = CreateStorageKey(Prefix_Candidate, stateAccount.VoteTo); - StorageItem storageValidator = engine.SnapshotCache.GetAndChange(key); + StorageItem storageValidator = engine.SnapshotCache.GetAndChange(key)!; CandidateState stateValidator = storageValidator.GetInteroperable(); stateValidator.Votes -= stateAccount.Balance; CheckCandidate(engine.SnapshotCache, stateAccount.VoteTo, stateValidator); @@ -483,7 +483,7 @@ private async ContractTask Vote(ApplicationEngine engine, UInt160 account, var latestGasPerVote = engine.SnapshotCache.TryGet(voterRewardKey) ?? BigInteger.Zero; stateAccount.LastGasPerVote = latestGasPerVote; } - ECPoint from = stateAccount.VoteTo; + ECPoint? from = stateAccount.VoteTo; stateAccount.VoteTo = voteTo; if (validatorNew != null) @@ -571,7 +571,7 @@ public ECPoint[] GetCommittee(IReadOnlyStore snapshot) /// account /// The state of the account. [ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.ReadStates)] - public NeoAccountState GetAccountState(IReadOnlyStore snapshot, UInt160 account) + public NeoAccountState? GetAccountState(IReadOnlyStore snapshot, UInt160 account) { var key = CreateStorageKey(Prefix_Account, account); return snapshot.TryGet(key, out var item) ? item.GetInteroperableClone() : null; @@ -659,7 +659,7 @@ public class NeoAccountState : AccountState /// /// The voting target of the account. This field can be . /// - public ECPoint VoteTo; + public ECPoint? VoteTo; public BigInteger LastGasPerVote; @@ -672,7 +672,7 @@ public override void FromStackItem(StackItem stackItem) LastGasPerVote = @struct[3].GetInteger(); } - public override StackItem ToStackItem(IReferenceCounter referenceCounter) + public override StackItem ToStackItem(IReferenceCounter? referenceCounter) { Struct @struct = (Struct)base.ToStackItem(referenceCounter); @struct.Add(BalanceHeight); @@ -694,7 +694,7 @@ public void FromStackItem(StackItem stackItem) Votes = @struct[1].GetInteger(); } - public StackItem ToStackItem(IReferenceCounter referenceCounter) + public StackItem ToStackItem(IReferenceCounter? referenceCounter) { return new Struct(referenceCounter) { Registered, Votes }; } @@ -711,7 +711,7 @@ protected override (ECPoint, BigInteger) ElementFromStackItem(StackItem item) return (ECPoint.DecodePoint(@struct[0].GetSpan(), ECCurve.Secp256r1), @struct[1].GetInteger()); } - protected override StackItem ElementToStackItem((ECPoint PublicKey, BigInteger Votes) element, IReferenceCounter referenceCounter) + protected override StackItem ElementToStackItem((ECPoint PublicKey, BigInteger Votes) element, IReferenceCounter? referenceCounter) { return new Struct(referenceCounter) { element.PublicKey.ToArray(), element.Votes }; } @@ -719,7 +719,7 @@ protected override StackItem ElementToStackItem((ECPoint PublicKey, BigInteger V private record GasDistribution { - public UInt160 Account { get; init; } + public required UInt160 Account { get; init; } public BigInteger Amount { get; init; } } } diff --git a/src/Neo/SmartContract/Native/Notary.cs b/src/Neo/SmartContract/Native/Notary.cs index 76e7a6050a..7cd188c1f8 100644 --- a/src/Neo/SmartContract/Native/Notary.cs +++ b/src/Neo/SmartContract/Native/Notary.cs @@ -9,7 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable #pragma warning disable IDE0051 using Neo.Cryptography; @@ -62,7 +61,7 @@ internal override async ContractTask OnPersistAsync(ApplicationEngine engine) { long nFees = 0; ECPoint[]? notaries = null; - foreach (var tx in engine.PersistingBlock.Transactions) + foreach (var tx in engine.PersistingBlock!.Transactions) { var attr = tx.GetAttribute(); if (attr is not null) @@ -138,12 +137,12 @@ private bool Verify(ApplicationEngine engine, byte[] signature) [ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.States)] private void OnNEP17Payment(ApplicationEngine engine, UInt160 from, BigInteger amount, StackItem data) { - if (engine.CallingScriptHash != GAS.Hash) throw new InvalidOperationException(string.Format("only GAS can be accepted for deposit, got {0}", engine.CallingScriptHash.ToString())); + if (engine.CallingScriptHash != GAS.Hash) throw new InvalidOperationException(string.Format("only GAS can be accepted for deposit, got {0}", engine.CallingScriptHash!.ToString())); if (data is not Array additionalParams || additionalParams.Count != 2) throw new FormatException("`data` parameter should be an array of 2 elements"); var to = from; if (!additionalParams[0].Equals(StackItem.Null)) to = additionalParams[0].GetSpan().ToArray().AsSerializable(); var till = (uint)additionalParams[1].GetInteger(); - var tx = (Transaction)engine.ScriptContainer; + var tx = (Transaction)engine.ScriptContainer!; var allowedChangeTill = tx.Sender == to; var currentHeight = Ledger.CurrentIndex(engine.SnapshotCache); if (till < currentHeight + 2) throw new ArgumentOutOfRangeException(string.Format("`till` shouldn't be less than the chain's height {0} + 1", currentHeight + 2)); @@ -335,12 +334,10 @@ public void FromStackItem(StackItem stackItem) Till = (uint)@struct[1].GetInteger(); } - public StackItem ToStackItem(IReferenceCounter referenceCounter) + public StackItem ToStackItem(IReferenceCounter? referenceCounter) { return new Struct(referenceCounter) { Amount, Till }; } } } } - -#nullable disable diff --git a/src/Neo/SmartContract/Native/OracleContract.cs b/src/Neo/SmartContract/Native/OracleContract.cs index 7ab60f2595..5dfe9992f6 100644 --- a/src/Neo/SmartContract/Native/OracleContract.cs +++ b/src/Neo/SmartContract/Native/OracleContract.cs @@ -62,7 +62,7 @@ private void SetPrice(ApplicationEngine engine, long price) if (price <= 0) throw new ArgumentOutOfRangeException(nameof(price), "Price must be positive"); AssertCommittee(engine); - engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_Price)).Set(price); + engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_Price))!.Set(price); } /// @@ -86,10 +86,10 @@ private ContractTask Finish(ApplicationEngine engine) { if (engine.InvocationStack.Count != 2) throw new InvalidOperationException(); if (engine.GetInvocationCounter() != 1) throw new InvalidOperationException(); - Transaction tx = (Transaction)engine.ScriptContainer; - OracleResponse response = tx.GetAttribute(); + Transaction tx = (Transaction)engine.ScriptContainer!; + OracleResponse? response = tx.GetAttribute(); if (response == null) throw new ArgumentException("Oracle response not found"); - OracleRequest request = GetRequest(engine.SnapshotCache, response.Id); + OracleRequest? request = GetRequest(engine.SnapshotCache, response.Id); if (request == null) throw new ArgumentException("Oracle request not found"); engine.SendNotification(Hash, "OracleResponse", new Array(engine.ReferenceCounter) { response.Id, request.OriginalTxid.ToArray() }); StackItem userData = BinarySerializer.Deserialize(request.UserData, engine.Limits, engine.ReferenceCounter); @@ -98,10 +98,10 @@ private ContractTask Finish(ApplicationEngine engine) private UInt256 GetOriginalTxid(ApplicationEngine engine) { - Transaction tx = (Transaction)engine.ScriptContainer; - OracleResponse response = tx.GetAttribute(); + Transaction tx = (Transaction)engine.ScriptContainer!; + OracleResponse? response = tx.GetAttribute(); if (response is null) return tx.Hash; - OracleRequest request = GetRequest(engine.SnapshotCache, response.Id); + OracleRequest request = GetRequest(engine.SnapshotCache, response.Id)!; return request.OriginalTxid; } @@ -111,7 +111,7 @@ private UInt256 GetOriginalTxid(ApplicationEngine engine) /// The snapshot used to read data. /// The id of the request. /// The pending request. Or if no request with the specified id is found. - public OracleRequest GetRequest(IReadOnlyStore snapshot, ulong id) + public OracleRequest? GetRequest(IReadOnlyStore snapshot, ulong id) { var key = CreateStorageKey(Prefix_Request, id); return snapshot.TryGet(key, out var item) ? item.GetInteroperableClone() : null; @@ -138,7 +138,7 @@ public OracleRequest GetRequest(IReadOnlyStore snapshot, ulong id) public IEnumerable<(ulong, OracleRequest)> GetRequestsByUrl(IReadOnlyStore snapshot, string url) { var listKey = CreateStorageKey(Prefix_IdList, GetUrlHash(url)); - IdList list = snapshot.TryGet(listKey, out var item) ? item.GetInteroperable() : null; + IdList? list = snapshot.TryGet(listKey, out var item) ? item.GetInteroperable() : null; if (list is null) yield break; foreach (ulong id in list) { @@ -164,11 +164,11 @@ internal override ContractTask InitializeAsync(ApplicationEngine engine, Hardfor internal override async ContractTask PostPersistAsync(ApplicationEngine engine) { - (UInt160 Account, BigInteger GAS)[] nodes = null; - foreach (Transaction tx in engine.PersistingBlock.Transactions) + (UInt160 Account, BigInteger GAS)[]? nodes = null; + foreach (Transaction tx in engine.PersistingBlock!.Transactions) { //Filter the response transactions - OracleResponse response = tx.GetAttribute(); + OracleResponse? response = tx.GetAttribute(); if (response is null) continue; //Remove the request from storage @@ -180,7 +180,7 @@ internal override async ContractTask PostPersistAsync(ApplicationEngine engine) //Remove the id from IdList key = CreateStorageKey(Prefix_IdList, GetUrlHash(request.Url)); - using (var sealInterop = engine.SnapshotCache.GetAndChange(key).GetInteroperable(out IdList list)) + using (var sealInterop = engine.SnapshotCache.GetAndChange(key)!.GetInteroperable(out IdList list)) { if (!list.Remove(response.Id)) throw new InvalidOperationException(); if (list.Count == 0) engine.SnapshotCache.Delete(key); @@ -207,7 +207,7 @@ internal override async ContractTask PostPersistAsync(ApplicationEngine engine) } [ContractMethod(RequiredCallFlags = CallFlags.States | CallFlags.AllowNotify)] - private async ContractTask Request(ApplicationEngine engine, string url, string filter, string callback, + private async ContractTask Request(ApplicationEngine engine, string url, string? filter, string callback, StackItem userData, long gasForResponse /* In the unit of datoshi, 1 datoshi = 1e-8 GAS */) { var urlSize = url.GetStrictUtf8ByteCount(); @@ -218,7 +218,7 @@ private async ContractTask Request(ApplicationEngine engine, string url, string if (filterSize > MaxFilterLength) throw new ArgumentException($"Filter size {filterSize} bytes exceeds maximum allowed size of {MaxFilterLength} bytes."); - var callbackSize = callback is null ? 0 : callback.GetStrictUtf8ByteCount(); + var callbackSize = callback.GetStrictUtf8ByteCount(); if (callbackSize > MaxCallbackLength) throw new ArgumentException($"Callback size {callbackSize} bytes exceeds maximum allowed size of {MaxCallbackLength} bytes."); @@ -235,12 +235,12 @@ private async ContractTask Request(ApplicationEngine engine, string url, string await GAS.Mint(engine, Hash, gasForResponse, false); //Increase the request id - var itemId = engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_RequestId)); + var itemId = engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_RequestId))!; var id = (ulong)(BigInteger)itemId; itemId.Add(1); //Put the request to storage - if (!ContractManagement.IsContract(engine.SnapshotCache, engine.CallingScriptHash)) + if (!ContractManagement.IsContract(engine.SnapshotCache, engine.CallingScriptHash!)) throw new InvalidOperationException(); var request = new OracleRequest { @@ -248,7 +248,7 @@ private async ContractTask Request(ApplicationEngine engine, string url, string GasForResponse = gasForResponse, Url = url, Filter = filter, - CallbackContract = engine.CallingScriptHash, + CallbackContract = engine.CallingScriptHash!, CallbackMethod = callback, UserData = BinarySerializer.Serialize(userData, MaxUserDataLength, engine.Limits.MaxStackSize) }; @@ -266,7 +266,7 @@ private async ContractTask Request(ApplicationEngine engine, string url, string engine.SendNotification(Hash, "OracleRequest", new Array(engine.ReferenceCounter) { id, - engine.CallingScriptHash.ToArray(), + engine.CallingScriptHash!.ToArray(), url, filter ?? StackItem.Null }); @@ -275,7 +275,7 @@ private async ContractTask Request(ApplicationEngine engine, string url, string [ContractMethod(CpuFee = 1 << 15)] private bool Verify(ApplicationEngine engine) { - Transaction tx = (Transaction)engine.ScriptContainer; + Transaction? tx = (Transaction?)engine.ScriptContainer; return tx?.GetAttribute() != null; } @@ -286,7 +286,7 @@ protected override ulong ElementFromStackItem(StackItem item) return (ulong)item.GetInteger(); } - protected override StackItem ElementToStackItem(ulong element, IReferenceCounter referenceCounter) + protected override StackItem ElementToStackItem(ulong element, IReferenceCounter? referenceCounter) { return element; } diff --git a/src/Neo/SmartContract/Native/OracleRequest.cs b/src/Neo/SmartContract/Native/OracleRequest.cs index 311e45184e..88dbed5793 100644 --- a/src/Neo/SmartContract/Native/OracleRequest.cs +++ b/src/Neo/SmartContract/Native/OracleRequest.cs @@ -24,7 +24,7 @@ public class OracleRequest : IInteroperable /// /// The original transaction that sent the related request. /// - public UInt256 OriginalTxid; + public required UInt256 OriginalTxid; /// /// The maximum amount of GAS that can be used when executing response callback. @@ -34,41 +34,41 @@ public class OracleRequest : IInteroperable /// /// The url of the request. /// - public string Url; + public required string Url; /// /// The filter for the response. /// - public string Filter; + public string? Filter; /// /// The hash of the callback contract. /// - public UInt160 CallbackContract; + public required UInt160 CallbackContract; /// /// The name of the callback method. /// - public string CallbackMethod; + public required string CallbackMethod; /// /// The user-defined object that will be passed to the callback. /// - public byte[] UserData; + public required byte[] UserData; public void FromStackItem(StackItem stackItem) { Array array = (Array)stackItem; OriginalTxid = new UInt256(array[0].GetSpan()); GasForResponse = (long)array[1].GetInteger(); - Url = array[2].GetString(); + Url = array[2].GetString()!; Filter = array[3].GetString(); CallbackContract = new UInt160(array[4].GetSpan()); - CallbackMethod = array[5].GetString(); + CallbackMethod = array[5].GetString()!; UserData = array[6].GetSpan().ToArray(); } - public StackItem ToStackItem(IReferenceCounter referenceCounter) + public StackItem ToStackItem(IReferenceCounter? referenceCounter) { return new Array(referenceCounter) { diff --git a/src/Neo/SmartContract/Native/PolicyContract.cs b/src/Neo/SmartContract/Native/PolicyContract.cs index bddcb70e73..3a1c8fa3a5 100644 --- a/src/Neo/SmartContract/Native/PolicyContract.cs +++ b/src/Neo/SmartContract/Native/PolicyContract.cs @@ -273,7 +273,7 @@ public void SetMillisecondsPerBlock(ApplicationEngine engine, uint value) AssertCommittee(engine); var oldTime = GetMillisecondsPerBlock(engine.SnapshotCache); - engine.SnapshotCache.GetAndChange(_millisecondsPerBlock).Set(value); + engine.SnapshotCache.GetAndChange(_millisecondsPerBlock)!.Set(value); engine.SendNotification(Hash, MillisecondsPerBlockChangedEventName, [new VM.Types.Integer(oldTime), new VM.Types.Integer(value)]); @@ -337,7 +337,7 @@ private void SetFeePerByte(ApplicationEngine engine, long value) throw new ArgumentOutOfRangeException(nameof(value), $"FeePerByte must be between [0, 100000000], got {value}"); AssertCommittee(engine); - engine.SnapshotCache.GetAndChange(_feePerByte).Set(value); + engine.SnapshotCache.GetAndChange(_feePerByte)!.Set(value); } [ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.States)] @@ -347,7 +347,7 @@ private void SetExecFeeFactor(ApplicationEngine engine, uint value) throw new ArgumentOutOfRangeException(nameof(value), $"ExecFeeFactor must be between [1, {MaxExecFeeFactor}], got {value}"); AssertCommittee(engine); - engine.SnapshotCache.GetAndChange(_execFeeFactor).Set(value); + engine.SnapshotCache.GetAndChange(_execFeeFactor)!.Set(value); } [ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.States)] @@ -357,7 +357,7 @@ private void SetStoragePrice(ApplicationEngine engine, uint value) throw new ArgumentOutOfRangeException(nameof(value), $"StoragePrice must be between [1, {MaxStoragePrice}], got {value}"); AssertCommittee(engine); - engine.SnapshotCache.GetAndChange(_storagePrice).Set(value); + engine.SnapshotCache.GetAndChange(_storagePrice)!.Set(value); } [ContractMethod(Hardfork.HF_Echidna, CpuFee = 1 << 15, RequiredCallFlags = CallFlags.States)] @@ -370,7 +370,7 @@ private void SetMaxValidUntilBlockIncrement(ApplicationEngine engine, uint value throw new InvalidOperationException($"MaxValidUntilBlockIncrement must be lower than MaxTraceableBlocks ({value} vs {mtb})"); AssertCommittee(engine); - engine.SnapshotCache.GetAndChange(_maxValidUntilBlockIncrement).Set(value); + engine.SnapshotCache.GetAndChange(_maxValidUntilBlockIncrement)!.Set(value); } /// @@ -394,7 +394,7 @@ private void SetMaxTraceableBlocks(ApplicationEngine engine, uint value) AssertCommittee(engine); - engine.SnapshotCache.GetAndChange(_maxTraceableBlocks).Set(value); + engine.SnapshotCache.GetAndChange(_maxTraceableBlocks)!.Set(value); } [ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.States)] diff --git a/src/Neo/SmartContract/Native/RoleManagement.cs b/src/Neo/SmartContract/Native/RoleManagement.cs index 25afa552f5..e8ce3fe77e 100644 --- a/src/Neo/SmartContract/Native/RoleManagement.cs +++ b/src/Neo/SmartContract/Native/RoleManagement.cs @@ -101,7 +101,7 @@ protected override ECPoint ElementFromStackItem(StackItem item) return ECPoint.DecodePoint(item.GetSpan(), ECCurve.Secp256r1); } - protected override StackItem ElementToStackItem(ECPoint element, IReferenceCounter referenceCounter) + protected override StackItem ElementToStackItem(ECPoint element, IReferenceCounter? referenceCounter) { return element.ToArray(); } diff --git a/src/Neo/SmartContract/Native/StdLib.cs b/src/Neo/SmartContract/Native/StdLib.cs index 326bb62f68..8a00cd3f9d 100644 --- a/src/Neo/SmartContract/Native/StdLib.cs +++ b/src/Neo/SmartContract/Native/StdLib.cs @@ -52,7 +52,9 @@ private static byte[] JsonSerialize(ApplicationEngine engine, StackItem item) [ContractMethod(CpuFee = 1 << 14)] private static StackItem JsonDeserialize(ApplicationEngine engine, byte[] json) { - return JsonSerializer.Deserialize(engine, JToken.Parse(json, 10), engine.Limits, engine.ReferenceCounter); + JToken? token = JToken.Parse(json, 10); + if (token is null) return StackItem.Null; + return JsonSerializer.Deserialize(engine, token, engine.Limits, engine.ReferenceCounter); } /// diff --git a/src/Neo/SmartContract/Native/TransactionState.cs b/src/Neo/SmartContract/Native/TransactionState.cs index a4c739b76a..ea79fba2d4 100644 --- a/src/Neo/SmartContract/Native/TransactionState.cs +++ b/src/Neo/SmartContract/Native/TransactionState.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - using Neo.Extensions; using Neo.Network.P2P.Payloads; using Neo.VM; @@ -60,7 +58,7 @@ void IInteroperable.FromStackItem(StackItem stackItem) State = (VMState)(byte)@struct[2].GetInteger(); } - StackItem IInteroperable.ToStackItem(IReferenceCounter referenceCounter) + StackItem IInteroperable.ToStackItem(IReferenceCounter? referenceCounter) { if (Transaction is null) return new Struct(referenceCounter) { BlockIndex }; @@ -68,5 +66,3 @@ StackItem IInteroperable.ToStackItem(IReferenceCounter referenceCounter) } } } - -#nullable disable diff --git a/src/Neo/SmartContract/Native/TrimmedBlock.cs b/src/Neo/SmartContract/Native/TrimmedBlock.cs index a7b4ffc847..0ec8d32ce4 100644 --- a/src/Neo/SmartContract/Native/TrimmedBlock.cs +++ b/src/Neo/SmartContract/Native/TrimmedBlock.cs @@ -29,12 +29,12 @@ public class TrimmedBlock : IInteroperable, ISerializable /// /// The header of the block. /// - public Header Header; + public required Header Header; /// /// The hashes of the transactions of the block. /// - public UInt256[] Hashes; + public required UInt256[] Hashes; /// /// The hash of the block. @@ -108,7 +108,7 @@ void IInteroperable.FromStackItem(StackItem stackItem) throw new NotSupportedException(); } - StackItem IInteroperable.ToStackItem(IReferenceCounter referenceCounter) + StackItem IInteroperable.ToStackItem(IReferenceCounter? referenceCounter) { return new Array(referenceCounter, [ diff --git a/src/Neo/SmartContract/NefFile.cs b/src/Neo/SmartContract/NefFile.cs index 6b41a275b0..438ae48553 100644 --- a/src/Neo/SmartContract/NefFile.cs +++ b/src/Neo/SmartContract/NefFile.cs @@ -18,6 +18,7 @@ using System.Buffers.Binary; using System.IO; using System.Linq; +using System.Runtime.CompilerServices; namespace Neo.SmartContract { @@ -52,17 +53,17 @@ public class NefFile : ISerializable /// /// The name and version of the compiler that generated this nef file. /// - public string Compiler { get; set; } + public required string Compiler { get; set; } /// /// The url of the source files. /// - public string Source { get; set; } + public required string Source { get; set; } /// /// The methods that to be called statically. /// - public MethodToken[] Tokens { get; set; } + public required MethodToken[] Tokens { get; set; } /// /// The script of the contract. @@ -96,7 +97,7 @@ public class NefFile : ISerializable public static NefFile Parse(ReadOnlyMemory memory, bool verify = true) { var reader = new MemoryReader(memory); - var nef = new NefFile(); + var nef = (NefFile)RuntimeHelpers.GetUninitializedObject(typeof(NefFile)); nef.Deserialize(ref reader, verify); return nef; } diff --git a/src/Neo/SmartContract/NotifyEventArgs.cs b/src/Neo/SmartContract/NotifyEventArgs.cs index 4a27bbcf42..d733c63b65 100644 --- a/src/Neo/SmartContract/NotifyEventArgs.cs +++ b/src/Neo/SmartContract/NotifyEventArgs.cs @@ -26,7 +26,7 @@ public class NotifyEventArgs : EventArgs, IInteroperable /// /// The container that containing the executed script. /// - public IVerifiable ScriptContainer { get; } + public IVerifiable? ScriptContainer { get; } /// /// The script hash of the contract that sends the log. @@ -50,7 +50,7 @@ public class NotifyEventArgs : EventArgs, IInteroperable /// The script hash of the contract that sends the log. /// The name of the event. /// The arguments of the event. - public NotifyEventArgs(IVerifiable container, UInt160 scriptHash, string eventName, Array state) + public NotifyEventArgs(IVerifiable? container, UInt160 scriptHash, string eventName, Array state) { ScriptContainer = container; ScriptHash = scriptHash; @@ -63,7 +63,7 @@ public void FromStackItem(StackItem stackItem) throw new NotSupportedException(); } - public StackItem ToStackItem(IReferenceCounter referenceCounter) + public StackItem ToStackItem(IReferenceCounter? referenceCounter) { return new Array(referenceCounter) { diff --git a/src/Neo/SmartContract/StorageItem.cs b/src/Neo/SmartContract/StorageItem.cs index 48fcd98337..b79ac95784 100644 --- a/src/Neo/SmartContract/StorageItem.cs +++ b/src/Neo/SmartContract/StorageItem.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - using Neo.Extensions; using Neo.IO; using Neo.VM; @@ -19,6 +17,7 @@ using System.IO; using System.Linq; using System.Numerics; +using System.Runtime.CompilerServices; namespace Neo.SmartContract { @@ -188,7 +187,7 @@ public void FromReplica(StorageItem replica) /// /// The type of the . /// The in the storage. - public T GetInteroperable() where T : IInteroperable, new() + public T GetInteroperable() where T : IInteroperable { _cache ??= GetInteroperableClone(); _value = null; @@ -201,7 +200,7 @@ public void FromReplica(StorageItem replica) /// Verify deserialization /// The type of the . /// The in the storage. - public T GetInteroperable(bool verify = true) where T : IInteroperableVerifiable, new() + public T GetInteroperable(bool verify = true) where T : IInteroperableVerifiable { _cache ??= GetInteroperableClone(verify); _value = null; @@ -213,7 +212,7 @@ public void FromReplica(StorageItem replica) /// /// The type of the . /// The in the storage. - public T GetInteroperableClone() where T : IInteroperable, new() + public T GetInteroperableClone() where T : IInteroperable { // If it's interoperable and not sealed if (_value.IsEmpty && _cache is T interoperable) @@ -222,7 +221,7 @@ public void FromReplica(StorageItem replica) return (T)interoperable.Clone(); } - interoperable = new T(); + interoperable = (T)RuntimeHelpers.GetUninitializedObject(typeof(T)); interoperable.FromStackItem(BinarySerializer.Deserialize(_value, ExecutionEngineLimits.Default)); return interoperable; } @@ -233,7 +232,7 @@ public void FromReplica(StorageItem replica) /// Verify deserialization /// The type of the . /// The in the storage. - public T GetInteroperableClone(bool verify = true) where T : IInteroperableVerifiable, new() + public T GetInteroperableClone(bool verify = true) where T : IInteroperableVerifiable { // If it's interoperable and not sealed if (_value.IsEmpty && _cache is T interoperable) @@ -241,7 +240,7 @@ public void FromReplica(StorageItem replica) return (T)interoperable.Clone(); } - interoperable = new T(); + interoperable = (T)RuntimeHelpers.GetUninitializedObject(typeof(T)); interoperable.FromStackItem(BinarySerializer.Deserialize(_value, ExecutionEngineLimits.Default), verify); return interoperable; } @@ -265,7 +264,7 @@ public void FromReplica(StorageItem replica) /// Verify deserialization /// The type of the . /// The that seal the item when disposed. - public IDisposable GetInteroperable(out T interop, bool verify = true) where T : IInteroperableVerifiable, new() + public IDisposable GetInteroperable(out T interop, bool verify = true) where T : IInteroperableVerifiable { interop = GetInteroperable(verify); return new SealInteroperable(this); @@ -309,5 +308,3 @@ public override string ToString() } } } - -#nullable disable diff --git a/src/Neo/SmartContract/StorageKey.cs b/src/Neo/SmartContract/StorageKey.cs index a5f147cf2e..5f870558e3 100644 --- a/src/Neo/SmartContract/StorageKey.cs +++ b/src/Neo/SmartContract/StorageKey.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - using Neo.Cryptography.ECC; using Neo.Extensions; using Neo.IO; @@ -369,5 +367,3 @@ public override string ToString() } } } - -#nullable disable diff --git a/src/Neo/UInt160.cs b/src/Neo/UInt160.cs index 215e8785c0..c1286118bf 100644 --- a/src/Neo/UInt160.cs +++ b/src/Neo/UInt160.cs @@ -61,15 +61,16 @@ public UInt160(ReadOnlySpan value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public int CompareTo(object obj) + public int CompareTo(object? obj) { if (ReferenceEquals(obj, this)) return 0; return CompareTo(obj as UInt160); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public int CompareTo(UInt160 other) + public int CompareTo(UInt160? other) { + if (other is null) return 1; var result = _value3.CompareTo(other._value3); if (result != 0) return result; result = _value2.CompareTo(other._value2); @@ -85,14 +86,14 @@ public void Deserialize(ref MemoryReader reader) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (ReferenceEquals(obj, this)) return true; return Equals(obj as UInt160); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(UInt160 other) + public bool Equals(UInt160? other) { if (other == null) return false; return _value1 == other._value1 && @@ -174,7 +175,7 @@ public override string ToString() /// /// if an is successfully parsed; otherwise, . /// - public static bool TryParse(string value, [NotNullWhen(true)] out UInt160 result) + public static bool TryParse(string value, [NotNullWhen(true)] out UInt160? result) { result = null; var data = value.AsSpan().TrimStartIgnoreCase("0x"); @@ -215,14 +216,14 @@ public static implicit operator UInt160(byte[] b) return new UInt160(b); } - public static bool operator ==(UInt160 left, UInt160 right) + public static bool operator ==(UInt160? left, UInt160? right) { if (left is null || right is null) return Equals(left, right); return left.Equals(right); } - public static bool operator !=(UInt160 left, UInt160 right) + public static bool operator !=(UInt160? left, UInt160? right) { if (left is null || right is null) return !Equals(left, right); diff --git a/src/Neo/UInt256.cs b/src/Neo/UInt256.cs index d5b19420ba..0d2cf2b0f7 100644 --- a/src/Neo/UInt256.cs +++ b/src/Neo/UInt256.cs @@ -61,14 +61,15 @@ public UInt256(ReadOnlySpan value) value.CopyTo(span); } - public int CompareTo(object obj) + public int CompareTo(object? obj) { if (ReferenceEquals(obj, this)) return 0; return CompareTo(obj as UInt256); } - public int CompareTo(UInt256 other) + public int CompareTo(UInt256? other) { + if (other is null) return 1; var result = _value4.CompareTo(other._value4); if (result != 0) return result; result = _value3.CompareTo(other._value3); @@ -86,13 +87,13 @@ public void Deserialize(ref MemoryReader reader) _value4 = reader.ReadUInt64(); } - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (ReferenceEquals(obj, this)) return true; return Equals(obj as UInt256); } - public bool Equals(UInt256 other) + public bool Equals(UInt256? other) { if (other is null) return false; return _value1 == other._value1 @@ -183,7 +184,7 @@ public override string ToString() /// if an is successfully parsed; otherwise, . /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryParse(string value, [NotNullWhen(true)] out UInt256 result) + public static bool TryParse(string value, [NotNullWhen(true)] out UInt256? result) { result = null; var data = value.AsSpan().TrimStartIgnoreCase("0x"); @@ -223,14 +224,14 @@ public static implicit operator UInt256(byte[] b) return new UInt256(b); } - public static bool operator ==(UInt256 left, UInt256 right) + public static bool operator ==(UInt256? left, UInt256? right) { if (ReferenceEquals(left, right)) return true; if (left is null || right is null) return false; return left.Equals(right); } - public static bool operator !=(UInt256 left, UInt256 right) + public static bool operator !=(UInt256? left, UInt256? right) { return !(left == right); } diff --git a/src/Neo/Wallets/AssetDescriptor.cs b/src/Neo/Wallets/AssetDescriptor.cs index 93479a19db..888bfeb2fd 100644 --- a/src/Neo/Wallets/AssetDescriptor.cs +++ b/src/Neo/Wallets/AssetDescriptor.cs @@ -66,7 +66,7 @@ public AssetDescriptor(DataCache snapshot, ProtocolSettings settings, UInt160 as if (engine.State != VMState.HALT) throw new ArgumentException($"Failed to execute 'decimals' or 'symbol' method for asset {assetId}. The contract execution did not complete successfully (VM state: {engine.State}).", nameof(assetId)); AssetId = assetId; AssetName = contract.Manifest.Name; - Symbol = engine.ResultStack.Pop().GetString(); + Symbol = engine.ResultStack.Pop().GetString()!; Decimals = (byte)engine.ResultStack.Pop().GetInteger(); } diff --git a/src/Neo/Wallets/Helper.cs b/src/Neo/Wallets/Helper.cs index 396f2c5f38..e58cdd7ed1 100644 --- a/src/Neo/Wallets/Helper.cs +++ b/src/Neo/Wallets/Helper.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - using Neo.Cryptography; using Neo.Extensions; using Neo.Network.P2P; @@ -232,5 +230,3 @@ public static long CalculateNetworkFee(this Transaction tx, DataCache snapshot, } } } - -#nullable disable diff --git a/src/Neo/Wallets/IWalletFactory.cs b/src/Neo/Wallets/IWalletFactory.cs index 83e6e8817f..e1e7dc4176 100644 --- a/src/Neo/Wallets/IWalletFactory.cs +++ b/src/Neo/Wallets/IWalletFactory.cs @@ -29,7 +29,7 @@ public interface IWalletFactory /// The path of the wallet file. /// The password of the wallet. /// The settings of the wallet. - public Wallet CreateWallet(string name, string path, string password, ProtocolSettings settings); + public Wallet CreateWallet(string? name, string path, string password, ProtocolSettings settings); /// /// Opens a wallet. diff --git a/src/Neo/Wallets/IWalletProvider.cs b/src/Neo/Wallets/IWalletProvider.cs index 719a35ca4f..eeba2a6b70 100644 --- a/src/Neo/Wallets/IWalletProvider.cs +++ b/src/Neo/Wallets/IWalletProvider.cs @@ -21,12 +21,12 @@ public interface IWalletProvider /// /// Triggered when a wallet is opened or closed. /// - event EventHandler WalletChanged; + event EventHandler WalletChanged; /// /// Get the currently opened instance. /// /// The opened wallet. Or if no wallet is opened. - Wallet GetWallet(); + Wallet? GetWallet(); } } diff --git a/src/Neo/Wallets/KeyPair.cs b/src/Neo/Wallets/KeyPair.cs index 21cafb9d99..fe5572f7c8 100644 --- a/src/Neo/Wallets/KeyPair.cs +++ b/src/Neo/Wallets/KeyPair.cs @@ -61,14 +61,14 @@ public KeyPair(byte[] privateKey) } } - public bool Equals(KeyPair other) + public bool Equals(KeyPair? other) { if (ReferenceEquals(this, other)) return true; if (other is null) return false; return PublicKey.Equals(other.PublicKey); } - public override bool Equals(object obj) + public override bool Equals(object? obj) { return Equals(obj as KeyPair); } diff --git a/src/Neo/Wallets/NEP6/NEP6Account.cs b/src/Neo/Wallets/NEP6/NEP6Account.cs index 22b08e4380..8e9a194ded 100644 --- a/src/Neo/Wallets/NEP6/NEP6Account.cs +++ b/src/Neo/Wallets/NEP6/NEP6Account.cs @@ -18,15 +18,15 @@ namespace Neo.Wallets.NEP6 sealed class NEP6Account : WalletAccount { private readonly NEP6Wallet wallet; - private string nep2key; - private string nep2KeyNew = null; - private KeyPair key; - public JToken Extra; + private string? nep2key; + private string? nep2KeyNew = null; + private KeyPair? key; + public JToken? Extra; public bool Decrypted => nep2key == null || key != null; public override bool HasKey => nep2key != null; - public NEP6Account(NEP6Wallet wallet, UInt160 scriptHash, string nep2key = null) + public NEP6Account(NEP6Wallet wallet, UInt160 scriptHash, string? nep2key = null) : base(scriptHash, wallet.ProtocolSettings) { this.wallet = wallet; @@ -41,17 +41,17 @@ public NEP6Account(NEP6Wallet wallet, UInt160 scriptHash, KeyPair key, string pa public static NEP6Account FromJson(JObject json, NEP6Wallet wallet) { - return new NEP6Account(wallet, json["address"].GetString().ToScriptHash(wallet.ProtocolSettings.AddressVersion), json["key"]?.GetString()) + return new NEP6Account(wallet, json["address"]!.GetString().ToScriptHash(wallet.ProtocolSettings.AddressVersion), json["key"]?.GetString()) { Label = json["label"]?.GetString(), - IsDefault = json["isDefault"].GetBoolean(), - Lock = json["lock"].GetBoolean(), - Contract = NEP6Contract.FromJson((JObject)json["contract"]), + IsDefault = json["isDefault"]!.GetBoolean(), + Lock = json["lock"]!.GetBoolean(), + Contract = NEP6Contract.FromJson((JObject)json["contract"]!), Extra = json["extra"] }; } - public override KeyPair GetKey() + public override KeyPair? GetKey() { if (nep2key == null) return null; if (key == null) @@ -61,7 +61,7 @@ public override KeyPair GetKey() return key; } - public KeyPair GetKey(string password) + public KeyPair? GetKey(string password) { if (nep2key == null) return null; if (key == null) @@ -79,7 +79,7 @@ public JObject ToJson() account["isDefault"] = IsDefault; account["lock"] = Lock; account["key"] = nep2key; - account["contract"] = ((NEP6Contract)Contract)?.ToJson(); + account["contract"] = ((NEP6Contract?)Contract)?.ToJson(); account["extra"] = Extra; return account; } @@ -88,7 +88,7 @@ public bool VerifyPassword(string password) { try { - Wallet.GetPrivateKeyFromNEP2(nep2key, password, ProtocolSettings.AddressVersion, wallet.Scrypt.N, wallet.Scrypt.R, wallet.Scrypt.P); + Wallet.GetPrivateKeyFromNEP2(nep2key!, password, ProtocolSettings.AddressVersion, wallet.Scrypt.N, wallet.Scrypt.R, wallet.Scrypt.P); return true; } catch (FormatException) @@ -103,7 +103,7 @@ public bool VerifyPassword(string password) internal bool ChangePasswordPrepare(string password_old, string password_new) { if (WatchOnly) return true; - KeyPair keyTemplate = key; + KeyPair? keyTemplate = key; if (nep2key == null) { if (keyTemplate == null) diff --git a/src/Neo/Wallets/NEP6/NEP6Contract.cs b/src/Neo/Wallets/NEP6/NEP6Contract.cs index ac92eaad81..601f8f4fca 100644 --- a/src/Neo/Wallets/NEP6/NEP6Contract.cs +++ b/src/Neo/Wallets/NEP6/NEP6Contract.cs @@ -18,18 +18,18 @@ namespace Neo.Wallets.NEP6 { internal class NEP6Contract : Contract { - public string[] ParameterNames; + public required string[] ParameterNames; public bool Deployed; - public static NEP6Contract FromJson(JObject json) + public static NEP6Contract? FromJson(JObject? json) { if (json == null) return null; return new NEP6Contract { - Script = Convert.FromBase64String(json["script"].AsString()), - ParameterList = ((JArray)json["parameters"]).Select(p => p["type"].GetEnum()).ToArray(), - ParameterNames = ((JArray)json["parameters"]).Select(p => p["name"].AsString()).ToArray(), - Deployed = json["deployed"].AsBoolean() + Script = Convert.FromBase64String(json["script"]!.AsString()), + ParameterList = ((JArray)json["parameters"]!).Select(p => p!["type"]!.GetEnum()).ToArray(), + ParameterNames = ((JArray)json["parameters"]!).Select(p => p!["name"]!.AsString()).ToArray(), + Deployed = json["deployed"]!.AsBoolean() }; } diff --git a/src/Neo/Wallets/NEP6/NEP6Wallet.cs b/src/Neo/Wallets/NEP6/NEP6Wallet.cs index c21e8abda0..8a0437fdd8 100644 --- a/src/Neo/Wallets/NEP6/NEP6Wallet.cs +++ b/src/Neo/Wallets/NEP6/NEP6Wallet.cs @@ -14,6 +14,7 @@ using Neo.SmartContract; using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Runtime.InteropServices; @@ -31,10 +32,10 @@ namespace Neo.Wallets.NEP6 public class NEP6Wallet : Wallet { private SecureString password; - private string name; + private string? name; private Version version; private readonly Dictionary accounts; - private readonly JToken extra; + private readonly JToken? extra; /// /// The parameters of the SCrypt algorithm used for encrypting and decrypting the private keys in the wallet. @@ -60,12 +61,12 @@ public class NEP6Wallet : Wallet /// The password of the wallet. /// The to be used by the wallet. /// The name of the wallet. If the wallet is loaded from an existing file, this parameter is ignored. - public NEP6Wallet(string path, string password, ProtocolSettings settings, string name = null) : base(path, settings) + public NEP6Wallet(string path, string password, ProtocolSettings settings, string? name = null) : base(path, settings) { this.password = password.ToSecureString(); if (File.Exists(path)) { - var wallet = (JObject)JToken.Parse(File.ReadAllBytes(path)); + var wallet = (JObject)JToken.Parse(File.ReadAllBytes(path))!; LoadFromJson(wallet, out Scrypt, out accounts, out extra); } else @@ -91,12 +92,13 @@ public NEP6Wallet(string path, string password, ProtocolSettings settings, JObje LoadFromJson(json, out Scrypt, out accounts, out extra); } - private void LoadFromJson(JObject wallet, out ScryptParameters scrypt, out Dictionary accounts, out JToken extra) + [MemberNotNull(nameof(version))] + private void LoadFromJson(JObject wallet, out ScryptParameters scrypt, out Dictionary accounts, out JToken? extra) { - version = Version.Parse(wallet["version"].AsString()); + version = Version.Parse(wallet["version"]!.AsString()); name = wallet["name"]?.AsString(); - scrypt = ScryptParameters.FromJson((JObject)wallet["scrypt"]); - accounts = ((JArray)wallet["accounts"]).Select(p => NEP6Account.FromJson((JObject)p, this)).ToDictionary(p => p.ScriptHash); + scrypt = ScryptParameters.FromJson((JObject)wallet["scrypt"]!); + accounts = ((JArray)wallet["accounts"]!).Select(p => NEP6Account.FromJson((JObject)p!, this)).ToDictionary(p => p.ScriptHash); extra = wallet["extra"]; if (!VerifyPasswordInternal(password.GetClearText())) throw new InvalidOperationException("Incorrect password provided for NEP6 wallet. Please verify the password and try again."); @@ -117,7 +119,7 @@ private void AddAccount(NEP6Account account) } else { - var contractOld = (NEP6Contract)accountOld.Contract; + var contractOld = (NEP6Contract?)accountOld.Contract; if (contractOld != null) { NEP6Contract contract = (NEP6Contract)account.Contract; @@ -159,7 +161,7 @@ public override WalletAccount CreateAccount(byte[] privateKey) return account; } - public override WalletAccount CreateAccount(Contract contract, KeyPair key = null) + public override WalletAccount CreateAccount(Contract contract, KeyPair? key = null) { if (contract is not NEP6Contract nep6contract) { @@ -211,11 +213,11 @@ public override bool DeleteAccount(UInt160 scriptHash) } } - public override WalletAccount GetAccount(UInt160 scriptHash) + public override WalletAccount? GetAccount(UInt160 scriptHash) { lock (accounts) { - accounts.TryGetValue(scriptHash, out NEP6Account account); + accounts.TryGetValue(scriptHash, out NEP6Account? account); return account; } } @@ -236,9 +238,9 @@ public override WalletAccount Import(X509Certificate2 cert) throw new PlatformNotSupportedException("Importing certificates is not supported on macOS."); } KeyPair key; - using (ECDsa ecdsa = cert.GetECDsaPrivateKey()) + using (ECDsa ecdsa = cert.GetECDsaPrivateKey() ?? throw new ArgumentException("The certificate must contains a private key.", nameof(cert))) { - key = new KeyPair(ecdsa.ExportParameters(true).D); + key = new KeyPair(ecdsa.ExportParameters(true).D!); } NEP6Contract contract = new() { @@ -328,7 +330,7 @@ private bool VerifyPasswordInternal(string password) { lock (accounts) { - NEP6Account account = accounts.Values.FirstOrDefault(p => !p.Decrypted); + NEP6Account? account = accounts.Values.FirstOrDefault(p => !p.Decrypted); if (account == null) { account = accounts.Values.FirstOrDefault(p => p.HasKey); diff --git a/src/Neo/Wallets/NEP6/NEP6WalletFactory.cs b/src/Neo/Wallets/NEP6/NEP6WalletFactory.cs index b45afd1972..cfe884fef2 100644 --- a/src/Neo/Wallets/NEP6/NEP6WalletFactory.cs +++ b/src/Neo/Wallets/NEP6/NEP6WalletFactory.cs @@ -23,7 +23,7 @@ public bool Handle(string path) return Path.GetExtension(path).Equals(".json", StringComparison.InvariantCultureIgnoreCase); } - public Wallet CreateWallet(string name, string path, string password, ProtocolSettings settings) + public Wallet CreateWallet(string? name, string path, string password, ProtocolSettings settings) { if (File.Exists(path)) throw new InvalidOperationException("The wallet file already exists."); diff --git a/src/Neo/Wallets/NEP6/ScryptParameters.cs b/src/Neo/Wallets/NEP6/ScryptParameters.cs index f90e076613..41bb822d32 100644 --- a/src/Neo/Wallets/NEP6/ScryptParameters.cs +++ b/src/Neo/Wallets/NEP6/ScryptParameters.cs @@ -58,7 +58,7 @@ public ScryptParameters(int n, int r, int p) /// The converted parameters. public static ScryptParameters FromJson(JObject json) { - return new ScryptParameters((int)json["n"].AsNumber(), (int)json["r"].AsNumber(), (int)json["p"].AsNumber()); + return new ScryptParameters((int)json["n"]!.AsNumber(), (int)json["r"]!.AsNumber(), (int)json["p"]!.AsNumber()); } /// diff --git a/src/Neo/Wallets/TransferOutput.cs b/src/Neo/Wallets/TransferOutput.cs index 57e7b197ee..fb1798e340 100644 --- a/src/Neo/Wallets/TransferOutput.cs +++ b/src/Neo/Wallets/TransferOutput.cs @@ -19,7 +19,7 @@ public class TransferOutput /// /// The id of the asset to transfer. /// - public UInt160 AssetId; + public required UInt160 AssetId; /// /// The amount of the asset to transfer. @@ -29,11 +29,11 @@ public class TransferOutput /// /// The account to transfer to. /// - public UInt160 ScriptHash; + public required UInt160 ScriptHash; /// /// The object to be passed to the transfer method of NEP-17. /// - public object Data; + public object? Data; } } diff --git a/src/Neo/Wallets/Wallet.cs b/src/Neo/Wallets/Wallet.cs index 032d2bbc4b..f7f9753032 100644 --- a/src/Neo/Wallets/Wallet.cs +++ b/src/Neo/Wallets/Wallet.cs @@ -91,7 +91,7 @@ public abstract class Wallet : ISigner /// The contract of the account. /// The private key of the account. /// The created account. - public abstract WalletAccount CreateAccount(Contract contract, KeyPair key = null); + public abstract WalletAccount CreateAccount(Contract contract, KeyPair? key = null); /// /// Creates a watch-only account for the wallet. @@ -117,7 +117,7 @@ public abstract class Wallet : ISigner /// /// The hash of the account. /// The account with the specified hash. - public abstract WalletAccount GetAccount(UInt160 scriptHash); + public abstract WalletAccount? GetAccount(UInt160 scriptHash); /// /// Gets all the accounts from the wallet. @@ -179,7 +179,7 @@ public WalletAccount CreateMultiSigAccount(int m, params ECPoint[] publicKeys) f => f.HasKey && f.Lock == false && - publicKeys.Contains(f.GetKey().PublicKey)); + publicKeys.Contains(f.GetKey()!.PublicKey)); return CreateAccount(contract, account?.GetKey()); } @@ -289,6 +289,7 @@ public IEnumerable GetMultiSigAccounts() => GetAccounts() .Where(static w => w.Lock == false && + w.Contract != null && IsMultiSigContract(w.Contract.Script)); /// @@ -296,7 +297,7 @@ public IEnumerable GetMultiSigAccounts() => /// /// The public key of the account. /// The account with the specified public key. - public WalletAccount GetAccount(ECPoint pubkey) + public WalletAccount? GetAccount(ECPoint pubkey) { return GetAccount(Contract.CreateSignatureRedeemScript(pubkey).ToScriptHash()); } @@ -305,9 +306,9 @@ public WalletAccount GetAccount(ECPoint pubkey) /// Gets the default account of the wallet. /// /// The default account of the wallet. - public virtual WalletAccount GetDefaultAccount() + public virtual WalletAccount? GetDefaultAccount() { - WalletAccount first = null; + WalletAccount? first = null; foreach (WalletAccount account in GetAccounts()) { if (account.IsDefault) return account; @@ -484,9 +485,9 @@ public virtual WalletAccount Import(X509Certificate2 cert) throw new PlatformNotSupportedException("Importing certificates is not supported on macOS."); } byte[] privateKey; - using (ECDsa ecdsa = cert.GetECDsaPrivateKey()) + using (ECDsa ecdsa = cert.GetECDsaPrivateKey() ?? throw new ArgumentException("The certificate must contains a private key.", nameof(cert))) { - privateKey = ecdsa.ExportParameters(true).D; + privateKey = ecdsa.ExportParameters(true).D!; } WalletAccount account = CreateAccount(privateKey); Array.Clear(privateKey, 0, privateKey.Length); @@ -535,7 +536,7 @@ public virtual WalletAccount Import(string nep2, string passphrase, int N = 1638 /// If null, will be used. /// /// The created transaction. - public Transaction MakeTransaction(DataCache snapshot, TransferOutput[] outputs, UInt160 from = null, Signer[] cosigners = null, Block persistingBlock = null) + public Transaction MakeTransaction(DataCache snapshot, TransferOutput[] outputs, UInt160? from = null, Signer[]? cosigners = null, Block? persistingBlock = null) { UInt160[] accounts; if (from is null) @@ -548,7 +549,7 @@ public Transaction MakeTransaction(DataCache snapshot, TransferOutput[] outputs, } Dictionary cosignerList = cosigners?.ToDictionary(p => p.Account) ?? new Dictionary(); byte[] script; - List<(UInt160 Account, BigInteger Value)> balances_gas = null; + List<(UInt160 Account, BigInteger Value)>? balances_gas = null; using (ScriptBuilder sb = new()) { foreach (var (assetId, group, sum) in outputs.GroupBy(p => p.AssetId, (k, g) => (k, g, g.Select(p => p.Value.Value).Sum()))) @@ -573,7 +574,7 @@ public Transaction MakeTransaction(DataCache snapshot, TransferOutput[] outputs, var balances_used = FindPayingAccounts(balances, output.Value.Value); foreach (var (account, value) in balances_used) { - if (cosignerList.TryGetValue(account, out Signer signer)) + if (cosignerList.TryGetValue(account, out Signer? signer)) { if (signer.Scopes != WitnessScope.Global) signer.Scopes |= WitnessScope.CalledByEntry; @@ -618,8 +619,8 @@ public Transaction MakeTransaction(DataCache snapshot, TransferOutput[] outputs, /// /// The created transaction. public Transaction MakeTransaction(DataCache snapshot, ReadOnlyMemory script, - UInt160 sender = null, Signer[] cosigners = null, TransactionAttribute[] attributes = null, - long maxGas = ApplicationEngine.TestModeGas, Block persistingBlock = null) + UInt160? sender = null, Signer[]? cosigners = null, TransactionAttribute[]? attributes = null, + long maxGas = ApplicationEngine.TestModeGas, Block? persistingBlock = null) { UInt160[] accounts; if (sender is null) @@ -639,7 +640,7 @@ public Transaction MakeTransaction(DataCache snapshot, ReadOnlyMemory scri private Transaction MakeTransaction(DataCache snapshot, ReadOnlyMemory script, Signer[] cosigners, TransactionAttribute[] attributes, List<(UInt160 Account, BigInteger Value)> balancesGas, - long maxGas = ApplicationEngine.TestModeGas, Block persistingBlock = null) + long maxGas = ApplicationEngine.TestModeGas, Block? persistingBlock = null) { foreach (var (account, value) in balancesGas) { @@ -651,6 +652,7 @@ private Transaction MakeTransaction(DataCache snapshot, ReadOnlyMemory scr ValidUntilBlock = NativeContract.Ledger.CurrentIndex(snapshot) + snapshot.GetMaxValidUntilBlockIncrement(ProtocolSettings), Signers = GetSigners(account, cosigners), Attributes = attributes, + Witnesses = null! }; // will try to execute 'transfer' script to check if it works @@ -693,14 +695,14 @@ public bool Sign(ContractParametersContext context) // Try to sign self-contained multiSig var multiSigContract = account.Contract; if (multiSigContract != null && - IsMultiSigContract(multiSigContract.Script, out int m, out ECPoint[] points)) + IsMultiSigContract(multiSigContract.Script, out int m, out ECPoint[]? points)) { foreach (var point in points) { account = GetAccount(point); if (account?.HasKey != true) continue; // check `Lock` or not? - var key = account.GetKey(); + var key = account.GetKey()!; var signature = context.Verifiable.Sign(key, context.Network); var ok = context.AddSignature(multiSigContract, key.PublicKey, signature); if (ok) m--; @@ -713,9 +715,9 @@ public bool Sign(ContractParametersContext context) else if (account.HasKey) { // Try to sign with regular accounts - var key = account.GetKey(); + var key = account.GetKey()!; var signature = context.Verifiable.Sign(key, context.Network); - fSuccess |= context.AddSignature(account.Contract, key.PublicKey, signature); + fSuccess |= context.AddSignature(account.Contract!, key.PublicKey, signature); continue; } } @@ -805,12 +807,12 @@ public bool ContainsSignable(ECPoint publicKey) /// public abstract void Save(); - public static Wallet Create(string name, string path, string password, ProtocolSettings settings) + public static Wallet? Create(string? name, string path, string password, ProtocolSettings settings) { return GetFactory(path)?.CreateWallet(name, path, password, settings); } - public static Wallet Open(string path, string password, ProtocolSettings settings) + public static Wallet? Open(string path, string password, ProtocolSettings settings) { return GetFactory(path)?.OpenWallet(path, password, settings); } @@ -825,10 +827,10 @@ public static Wallet Open(string path, string password, ProtocolSettings setting /// The created new wallet. public static Wallet Migrate(string path, string oldPath, string password, ProtocolSettings settings) { - IWalletFactory factoryOld = GetFactory(oldPath); + IWalletFactory? factoryOld = GetFactory(oldPath); if (factoryOld is null) throw new InvalidOperationException("The old wallet file format is not supported."); - IWalletFactory factoryNew = GetFactory(path); + IWalletFactory? factoryNew = GetFactory(path); if (factoryNew is null) throw new InvalidOperationException("The new wallet file format is not supported."); @@ -837,12 +839,13 @@ public static Wallet Migrate(string path, string oldPath, string password, Proto foreach (WalletAccount account in oldWallet.GetAccounts()) { - newWallet.CreateAccount(account.Contract, account.GetKey()); + if (account.Contract != null) + newWallet.CreateAccount(account.Contract, account.GetKey()); } return newWallet; } - private static IWalletFactory GetFactory(string path) + private static IWalletFactory? GetFactory(string path) { return factories.FirstOrDefault(p => p.Handle(path)); } diff --git a/src/Neo/Wallets/WalletAccount.cs b/src/Neo/Wallets/WalletAccount.cs index 96213db1f3..7d46668f26 100644 --- a/src/Neo/Wallets/WalletAccount.cs +++ b/src/Neo/Wallets/WalletAccount.cs @@ -31,7 +31,7 @@ public abstract class WalletAccount /// /// The label of the account. /// - public string Label; + public string? Label; /// /// Indicates whether the account is the default account in the wallet. @@ -46,7 +46,7 @@ public abstract class WalletAccount /// /// The contract of the account. /// - public Contract Contract; + public Contract? Contract; /// /// The address of the account. @@ -67,7 +67,7 @@ public abstract class WalletAccount /// Gets the private key of the account. /// /// The private key of the account. Or if there is no private key in the account. - public abstract KeyPair GetKey(); + public abstract KeyPair? GetKey(); /// /// Initializes a new instance of the class. diff --git a/src/Plugins/ApplicationLogs/LogReader.cs b/src/Plugins/ApplicationLogs/LogReader.cs index 38124ffecd..d660fe34ec 100644 --- a/src/Plugins/ApplicationLogs/LogReader.cs +++ b/src/Plugins/ApplicationLogs/LogReader.cs @@ -141,12 +141,17 @@ public JToken GetApplicationLog(UInt256 hash, string triggerType = "") [ConsoleCommand("log block", Category = "ApplicationLog Commands")] internal void OnGetBlockCommand(string blockHashOrIndex, string? eventName = null) { - UInt256 blockhash; + UInt256? blockhash; if (uint.TryParse(blockHashOrIndex, out var blockIndex)) { blockhash = NativeContract.Ledger.GetBlockHash(_neosystem.StoreView, blockIndex); } - else if (UInt256.TryParse(blockHashOrIndex, out blockhash) == false) + else + { + UInt256.TryParse(blockHashOrIndex, out blockhash); + } + + if (blockhash is null) { ConsoleHelper.Error("Invalid block hash or index."); return; @@ -235,9 +240,9 @@ void ICommittingHandler.Blockchain_Committing_Handler(NeoSystem system, Block bl { foreach (var appEng in applicationExecutedList.Where(w => w.Transaction != null)) { - var logs = _logEvents.Where(w => w.ScriptContainer.Hash == appEng.Transaction.Hash).ToList(); + var logs = _logEvents.Where(w => w.ScriptContainer?.Hash == appEng.Transaction!.Hash).ToList(); if (logs.Any()) - _neostore.PutTransactionEngineLogState(appEng.Transaction.Hash, logs); + _neostore.PutTransactionEngineLogState(appEng.Transaction!.Hash, logs); } _logEvents.Clear(); } @@ -341,7 +346,7 @@ private string GetMethodParameterName(UInt160 scriptHash, string methodName, uin if (contract == null) return $"{parameterIndex}"; var contractEvent = contract.Manifest.Abi.Events.SingleOrDefault(s => s.Name == methodName && (uint)s.Parameters.Length == ncount); - if (contractEvent == null) + if (contractEvent is null) return $"{parameterIndex}"; return contractEvent.Parameters[parameterIndex].Name; } diff --git a/src/Plugins/ApplicationLogs/Store/States/ContractLogState.cs b/src/Plugins/ApplicationLogs/Store/States/ContractLogState.cs index cea627315a..b8292cc954 100644 --- a/src/Plugins/ApplicationLogs/Store/States/ContractLogState.cs +++ b/src/Plugins/ApplicationLogs/Store/States/ContractLogState.cs @@ -9,6 +9,7 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +using Neo.Extensions; using Neo.IO; using Neo.Ledger; using Neo.SmartContract; @@ -39,7 +40,7 @@ public static ContractLogState Create(Blockchain.ApplicationExecuted application public override void Deserialize(ref MemoryReader reader) { - TransactionHash.Deserialize(ref reader); + TransactionHash = reader.ReadSerializable(); Trigger = (TriggerType)reader.ReadByte(); base.Deserialize(ref reader); } diff --git a/src/Plugins/ApplicationLogs/Store/States/EngineLogState.cs b/src/Plugins/ApplicationLogs/Store/States/EngineLogState.cs index 4c93ef3090..3cc34797d2 100644 --- a/src/Plugins/ApplicationLogs/Store/States/EngineLogState.cs +++ b/src/Plugins/ApplicationLogs/Store/States/EngineLogState.cs @@ -34,7 +34,7 @@ public static EngineLogState Create(UInt160 scriptHash, string message) => public virtual void Deserialize(ref MemoryReader reader) { - ScriptHash.Deserialize(ref reader); + ScriptHash = reader.ReadSerializable(); // It should be safe because it filled from a transaction's logs. Message = reader.ReadVarString(); } diff --git a/src/Plugins/ApplicationLogs/Store/States/NotifyLogState.cs b/src/Plugins/ApplicationLogs/Store/States/NotifyLogState.cs index 355dfd435a..429d695a95 100644 --- a/src/Plugins/ApplicationLogs/Store/States/NotifyLogState.cs +++ b/src/Plugins/ApplicationLogs/Store/States/NotifyLogState.cs @@ -38,7 +38,7 @@ public static NotifyLogState Create(NotifyEventArgs notifyItem, Guid[] stackItem public virtual void Deserialize(ref MemoryReader reader) { - ScriptHash.Deserialize(ref reader); + ScriptHash = reader.ReadSerializable(); EventName = reader.ReadVarString(); // It should be safe because it filled from a transaction's notifications. diff --git a/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.cs b/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.cs index 34a138cc23..b4b8e07c2b 100644 --- a/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.cs +++ b/src/Plugins/DBFTPlugin/Consensus/ConsensusContext.cs @@ -204,12 +204,15 @@ public void Reset(byte viewNumber) Header = new Header { PrevHash = NativeContract.Ledger.CurrentHash(Snapshot), + MerkleRoot = null!, Index = height + 1, NextConsensus = Contract.GetBFTAddress( NeoToken.ShouldRefreshCommittee(height + 1, neoSystem.Settings.CommitteeMembersCount) ? NativeContract.NEO.ComputeNextBlockValidators(Snapshot, neoSystem.Settings) : - NativeContract.NEO.GetNextBlockValidators(Snapshot, neoSystem.Settings.ValidatorsCount)) - } + NativeContract.NEO.GetNextBlockValidators(Snapshot, neoSystem.Settings.ValidatorsCount)), + Witness = null! + }, + Transactions = null! }; TimePerBlock = neoSystem.GetTimePerBlock(); var pv = Validators; diff --git a/src/Plugins/DBFTPlugin/Consensus/ConsensusService.Check.cs b/src/Plugins/DBFTPlugin/Consensus/ConsensusService.Check.cs index ded2f12358..cf4f06c880 100644 --- a/src/Plugins/DBFTPlugin/Consensus/ConsensusService.Check.cs +++ b/src/Plugins/DBFTPlugin/Consensus/ConsensusService.Check.cs @@ -49,7 +49,7 @@ private bool CheckPrepareResponse() ExtendTimerByFactor(2); Log($"Sending {nameof(PrepareResponse)}"); - localNode.Tell(new LocalNode.SendDirectly { Inventory = context.MakePrepareResponse() }); + localNode.Tell(new LocalNode.SendDirectly(context.MakePrepareResponse())); CheckPreparations(); } return true; @@ -79,7 +79,7 @@ private void CheckExpectedView(byte viewNumber) // Communicate the network about my agreement to move to `viewNumber` // if my last change view payload, `message`, has NewViewNumber lower than current view to change if (message is null || message.NewViewNumber < viewNumber) - localNode.Tell(new LocalNode.SendDirectly { Inventory = context.MakeChangeView(ChangeViewReason.ChangeAgreement) }); + localNode.Tell(new LocalNode.SendDirectly(context.MakeChangeView(ChangeViewReason.ChangeAgreement))); } InitializeConsensus(viewNumber); } @@ -92,7 +92,7 @@ private void CheckPreparations() ExtensiblePayload payload = context.MakeCommit(); Log($"Sending {nameof(Commit)}"); context.Save(); - localNode.Tell(new LocalNode.SendDirectly { Inventory = payload }); + localNode.Tell(new LocalNode.SendDirectly(payload)); // Set timer, so we will resend the commit in case of a networking issue ChangeTimer(context.TimePerBlock); CheckCommits(); diff --git a/src/Plugins/DBFTPlugin/Consensus/ConsensusService.OnMessage.cs b/src/Plugins/DBFTPlugin/Consensus/ConsensusService.OnMessage.cs index 1db1c56383..4998f976b0 100644 --- a/src/Plugins/DBFTPlugin/Consensus/ConsensusService.OnMessage.cs +++ b/src/Plugins/DBFTPlugin/Consensus/ConsensusService.OnMessage.cs @@ -160,10 +160,7 @@ private void OnPrepareRequestReceived(ExtensiblePayload payload, PrepareRequest if (context.Transactions.Count < context.TransactionHashes.Length) { UInt256[] hashes = context.TransactionHashes.Where(i => !context.Transactions.ContainsKey(i)).ToArray(); - taskManager.Tell(new TaskManager.RestartTasks - { - Payload = InvPayload.Create(InventoryType.TX, hashes) - }); + taskManager.Tell(new TaskManager.RestartTasks(InvPayload.Create(InventoryType.TX, hashes))); } } @@ -315,7 +312,7 @@ private void OnRecoveryRequestReceived(ExtensiblePayload payload, ConsensusMessa if (!shouldSendRecovery) return; } - localNode.Tell(new LocalNode.SendDirectly { Inventory = context.MakeRecoveryMessage() }); + localNode.Tell(new LocalNode.SendDirectly(context.MakeRecoveryMessage())); } } } diff --git a/src/Plugins/DBFTPlugin/Consensus/ConsensusService.cs b/src/Plugins/DBFTPlugin/Consensus/ConsensusService.cs index 51f9d0a327..34108c51ba 100644 --- a/src/Plugins/DBFTPlugin/Consensus/ConsensusService.cs +++ b/src/Plugins/DBFTPlugin/Consensus/ConsensusService.cs @@ -150,10 +150,7 @@ private void OnStart() { if (context.Transactions != null) { - blockchain.Ask(new FillMemoryPool - { - Transactions = context.Transactions.Values - }).Wait(); + blockchain.Ask(new FillMemoryPool(context.Transactions.Values)).Wait(); } if (context.CommitSent) { @@ -181,7 +178,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() }); + localNode.Tell(new LocalNode.SendDirectly(context.MakeRecoveryMessage())); ChangeTimer(TimeSpan.FromMilliseconds((int)context.TimePerBlock.TotalMilliseconds << 1)); } else @@ -201,7 +198,7 @@ private void OnTimer(Timer timer) private void SendPrepareRequest() { Log($"Sending {nameof(PrepareRequest)}: height={context.Block.Index} view={context.ViewNumber}"); - localNode.Tell(new LocalNode.SendDirectly { Inventory = context.MakePrepareRequest() }); + localNode.Tell(new LocalNode.SendDirectly(context.MakePrepareRequest())); if (context.Validators.Length == 1) CheckPreparations(); @@ -217,7 +214,7 @@ private void SendPrepareRequest() private void RequestRecovery() { Log($"Sending {nameof(RecoveryRequest)}: height={context.Block.Index} view={context.ViewNumber} nc={context.CountCommitted} nf={context.CountFailed}"); - localNode.Tell(new LocalNode.SendDirectly { Inventory = context.MakeRecoveryRequest() }); + localNode.Tell(new LocalNode.SendDirectly(context.MakeRecoveryRequest())); } private void RequestChangeView(ChangeViewReason reason) @@ -236,14 +233,14 @@ private void RequestChangeView(ChangeViewReason reason) else { Log($"Sending {nameof(ChangeView)}: height={context.Block.Index} view={context.ViewNumber} nv={expectedView} nc={context.CountCommitted} nf={context.CountFailed} reason={reason}"); - localNode.Tell(new LocalNode.SendDirectly { Inventory = context.MakeChangeView(reason) }); + localNode.Tell(new LocalNode.SendDirectly(context.MakeChangeView(reason))); CheckExpectedView(expectedView); } } private bool ReverifyAndProcessPayload(ExtensiblePayload payload) { - RelayResult relayResult = blockchain.Ask(new Reverify { Inventories = new IInventory[] { payload } }).Result; + RelayResult relayResult = blockchain.Ask(new Reverify(new IInventory[] { payload })).Result; if (relayResult.Result != VerifyResult.Succeed) return false; OnConsensusPayload(payload); return true; diff --git a/src/Plugins/LevelDBStore/Plugins/Storage/LevelDBStore.cs b/src/Plugins/LevelDBStore/Plugins/Storage/LevelDBStore.cs index 916b3e43b6..5359790445 100644 --- a/src/Plugins/LevelDBStore/Plugins/Storage/LevelDBStore.cs +++ b/src/Plugins/LevelDBStore/Plugins/Storage/LevelDBStore.cs @@ -25,8 +25,9 @@ public LevelDBStore() StoreFactory.RegisterProvider(this); } - public IStore GetStore(string path) + public IStore GetStore(string? path) { + ArgumentNullException.ThrowIfNull(path); if (Environment.CommandLine.Split(' ').Any(p => p == "/repair" || p == "--repair")) DB.Repair(path, Options.Default); return new Store(path); diff --git a/src/Plugins/RestServer/Controllers/v1/LedgerController.cs b/src/Plugins/RestServer/Controllers/v1/LedgerController.cs index a2d3d13720..609fa7b3c1 100644 --- a/src/Plugins/RestServer/Controllers/v1/LedgerController.cs +++ b/src/Plugins/RestServer/Controllers/v1/LedgerController.cs @@ -269,9 +269,8 @@ public IActionResult GetTransactionWitnesses( [FromRoute( Name = "hash")] UInt256 hash) { - if (NativeContract.Ledger.ContainsTransaction(_neoSystem.StoreView, hash) == false) - throw new TransactionNotFoundException(hash); - var tx = NativeContract.Ledger.GetTransaction(_neoSystem.StoreView, hash); + var tx = NativeContract.Ledger.GetTransaction(_neoSystem.StoreView, hash) + ?? throw new TransactionNotFoundException(hash); return Ok(tx.Witnesses); } @@ -288,9 +287,8 @@ public IActionResult GetTransactionSigners( [FromRoute( Name = "hash")] UInt256 hash) { - if (NativeContract.Ledger.ContainsTransaction(_neoSystem.StoreView, hash) == false) - throw new TransactionNotFoundException(hash); - var tx = NativeContract.Ledger.GetTransaction(_neoSystem.StoreView, hash); + var tx = NativeContract.Ledger.GetTransaction(_neoSystem.StoreView, hash) + ?? throw new TransactionNotFoundException(hash); return Ok(tx.Signers); } @@ -307,9 +305,8 @@ public IActionResult GetTransactionAttributes( [FromRoute( Name = "hash")] UInt256 hash) { - if (NativeContract.Ledger.ContainsTransaction(_neoSystem.StoreView, hash) == false) - throw new TransactionNotFoundException(hash); - var tx = NativeContract.Ledger.GetTransaction(_neoSystem.StoreView, hash); + var tx = NativeContract.Ledger.GetTransaction(_neoSystem.StoreView, hash) + ?? throw new TransactionNotFoundException(hash); return Ok(tx.Attributes); } diff --git a/src/Plugins/RestServer/Extensions/UInt160Extensions.cs b/src/Plugins/RestServer/Extensions/UInt160Extensions.cs index afe2c8fe6c..ab5724ccc9 100644 --- a/src/Plugins/RestServer/Extensions/UInt160Extensions.cs +++ b/src/Plugins/RestServer/Extensions/UInt160Extensions.cs @@ -19,6 +19,7 @@ internal static class UInt160Extensions public static bool IsValidNep17(this UInt160 scriptHash) { var contractState = NativeContract.ContractManagement.GetContract(RestServerPlugin.NeoSystem!.StoreView, scriptHash); + if (contractState is null) return false; return ContractHelper.IsNep17Supported(contractState); } diff --git a/src/Plugins/RestServer/Helpers/ContractHelper.cs b/src/Plugins/RestServer/Helpers/ContractHelper.cs index cbb8ef63d4..e36e808f85 100644 --- a/src/Plugins/RestServer/Helpers/ContractHelper.cs +++ b/src/Plugins/RestServer/Helpers/ContractHelper.cs @@ -57,16 +57,16 @@ public static bool IsNep17Supported(ContractState contractState) var balanceOfMethod = manifest.Abi.GetMethod("balanceOf", 1); var transferMethod = manifest.Abi.GetMethod("transfer", 4); - var symbolValid = symbolMethod.Safe == true && + var symbolValid = symbolMethod?.Safe == true && symbolMethod.ReturnType == ContractParameterType.String; - var decimalsValid = decimalsMethod.Safe == true && + var decimalsValid = decimalsMethod?.Safe == true && decimalsMethod.ReturnType == ContractParameterType.Integer; - var totalSupplyValid = totalSupplyMethod.Safe == true && + var totalSupplyValid = totalSupplyMethod?.Safe == true && totalSupplyMethod.ReturnType == ContractParameterType.Integer; - var balanceOfValid = balanceOfMethod.Safe == true && + var balanceOfValid = balanceOfMethod?.Safe == true && balanceOfMethod.ReturnType == ContractParameterType.Integer && balanceOfMethod.Parameters[0].Type == ContractParameterType.Hash160; - var transferValid = transferMethod.Safe == false && + var transferValid = transferMethod?.Safe == false && transferMethod.ReturnType == ContractParameterType.Boolean && transferMethod.Parameters[0].Type == ContractParameterType.Hash160 && transferMethod.Parameters[1].Type == ContractParameterType.Hash160 && @@ -111,29 +111,29 @@ public static bool IsNep11Supported(ContractState contractState) var transferMethod1 = manifest.Abi.GetMethod("transfer", 3); var transferMethod2 = manifest.Abi.GetMethod("transfer", 5); - var symbolValid = symbolMethod.Safe == true && + var symbolValid = symbolMethod?.Safe == true && symbolMethod.ReturnType == ContractParameterType.String; - var decimalsValid = decimalsMethod.Safe == true && + var decimalsValid = decimalsMethod?.Safe == true && decimalsMethod.ReturnType == ContractParameterType.Integer; - var totalSupplyValid = totalSupplyMethod.Safe == true && + var totalSupplyValid = totalSupplyMethod?.Safe == true && totalSupplyMethod.ReturnType == ContractParameterType.Integer; - var balanceOfValid1 = balanceOfMethod1.Safe == true && + var balanceOfValid1 = balanceOfMethod1?.Safe == true && balanceOfMethod1.ReturnType == ContractParameterType.Integer && balanceOfMethod1.Parameters[0].Type == ContractParameterType.Hash160; var balanceOfValid2 = balanceOfMethod2?.Safe == true && balanceOfMethod2?.ReturnType == ContractParameterType.Integer && balanceOfMethod2?.Parameters[0].Type == ContractParameterType.Hash160 && balanceOfMethod2?.Parameters[0].Type == ContractParameterType.ByteArray; - var tokensOfValid = tokensOfMethod.Safe == true && + var tokensOfValid = tokensOfMethod?.Safe == true && tokensOfMethod.ReturnType == ContractParameterType.InteropInterface && tokensOfMethod.Parameters[0].Type == ContractParameterType.Hash160; - var ownerOfValid1 = ownerOfMethod.Safe == true && + var ownerOfValid1 = ownerOfMethod?.Safe == true && ownerOfMethod.ReturnType == ContractParameterType.Hash160 && ownerOfMethod.Parameters[0].Type == ContractParameterType.ByteArray; - var ownerOfValid2 = ownerOfMethod.Safe == true && + var ownerOfValid2 = ownerOfMethod?.Safe == true && ownerOfMethod.ReturnType == ContractParameterType.InteropInterface && ownerOfMethod.Parameters[0].Type == ContractParameterType.ByteArray; - var transferValid1 = transferMethod1.Safe == false && + var transferValid1 = transferMethod1?.Safe == false && transferMethod1.ReturnType == ContractParameterType.Boolean && transferMethod1.Parameters[0].Type == ContractParameterType.Hash160 && transferMethod1.Parameters[1].Type == ContractParameterType.ByteArray && diff --git a/src/Plugins/RestServer/Helpers/ScriptHelper.cs b/src/Plugins/RestServer/Helpers/ScriptHelper.cs index e3e16ff83d..ee1770b3d4 100644 --- a/src/Plugins/RestServer/Helpers/ScriptHelper.cs +++ b/src/Plugins/RestServer/Helpers/ScriptHelper.cs @@ -65,7 +65,7 @@ public static ApplicationEngine InvokeScript(ReadOnlyMemory script, Signer Signers = signers, Attributes = [], Script = script, - Witnesses = witnesses + Witnesses = witnesses ?? [] }; return ApplicationEngine.Run(script, snapshot, tx, settings: neoSystem.Settings, gas: RestServerSettings.Current.MaxGasInvoke); } diff --git a/src/Plugins/RestServer/Newtonsoft/Json/WitnessConditionJsonConverter.cs b/src/Plugins/RestServer/Newtonsoft/Json/WitnessConditionJsonConverter.cs index 1dba6b5959..1da884f6e2 100644 --- a/src/Plugins/RestServer/Newtonsoft/Json/WitnessConditionJsonConverter.cs +++ b/src/Plugins/RestServer/Newtonsoft/Json/WitnessConditionJsonConverter.cs @@ -78,7 +78,7 @@ public static WitnessCondition FromJson(JObject json) break; case WitnessConditionType.ScriptHash: valueProp = json.Properties().Single(s => EqualsIgnoreCase(s.Name, "hash")); - return new ScriptHashCondition() { Hash = UInt160.Parse(valueProp.Value()) }; + return new ScriptHashCondition() { Hash = UInt160.Parse(valueProp.Value()!) }; case WitnessConditionType.Group: valueProp = json.Properties().Single(s => EqualsIgnoreCase(s.Name, "group")); return new GroupCondition() { Group = ECPoint.Parse(valueProp.Value() ?? throw new NullReferenceException("In the witness json data, group is null."), ECCurve.Secp256r1) }; @@ -86,7 +86,7 @@ public static WitnessCondition FromJson(JObject json) return new CalledByEntryCondition(); case WitnessConditionType.CalledByContract: valueProp = json.Properties().Single(s => EqualsIgnoreCase(s.Name, "hash")); - return new CalledByContractCondition { Hash = UInt160.Parse(valueProp.Value()) }; + return new CalledByContractCondition { Hash = UInt160.Parse(valueProp.Value()!) }; case WitnessConditionType.CalledByGroup: valueProp = json.Properties().Single(s => EqualsIgnoreCase(s.Name, "group")); return new CalledByGroupCondition { Group = ECPoint.Parse(valueProp.Value() ?? throw new NullReferenceException("In the witness json data, group is null."), ECCurve.Secp256r1) }; diff --git a/src/Plugins/RestServer/RestServerPlugin.cs b/src/Plugins/RestServer/RestServerPlugin.cs index db7191e5b7..f9aa5c2a65 100644 --- a/src/Plugins/RestServer/RestServerPlugin.cs +++ b/src/Plugins/RestServer/RestServerPlugin.cs @@ -32,8 +32,8 @@ public partial class RestServerPlugin : Plugin #region Static Globals - internal static NeoSystem? NeoSystem { get; private set; } - internal static LocalNode? LocalNode { get; private set; } + internal static NeoSystem NeoSystem { get; private set; } = null!; + internal static LocalNode LocalNode { get; private set; } = null!; #endregion diff --git a/src/Plugins/RestServer/RestServerUtility.JTokens.cs b/src/Plugins/RestServer/RestServerUtility.JTokens.cs index 1a5cf34619..aa1c3be147 100644 --- a/src/Plugins/RestServer/RestServerUtility.JTokens.cs +++ b/src/Plugins/RestServer/RestServerUtility.JTokens.cs @@ -59,7 +59,7 @@ public static JToken BlockToJToken(Block block, global::Newtonsoft.Json.JsonSeri block.NextConsensus, Witness = WitnessToJToken(block.Witness, serializer), block.Size, - Confirmations = NativeContract.Ledger.CurrentIndex(RestServerPlugin.NeoSystem?.StoreView) - block.Index + 1, + Confirmations = NativeContract.Ledger.CurrentIndex(RestServerPlugin.NeoSystem.StoreView) - block.Index + 1, Transactions = block.Transactions.Select(s => TransactionToJToken(s, serializer)), }, serializer); diff --git a/src/Plugins/RestServer/RestServerUtility.cs b/src/Plugins/RestServer/RestServerUtility.cs index 35ef962d8c..26061eee49 100644 --- a/src/Plugins/RestServer/RestServerUtility.cs +++ b/src/Plugins/RestServer/RestServerUtility.cs @@ -19,6 +19,7 @@ using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Numerics; using Array = Neo.VM.Types.Array; @@ -38,7 +39,7 @@ public static UInt160 ConvertToScriptHash(string address, ProtocolSettings setti return address.ToScriptHash(settings.AddressVersion); } - public static bool TryConvertToScriptHash(string address, ProtocolSettings settings, out UInt160 scriptHash) + public static bool TryConvertToScriptHash(string address, ProtocolSettings settings, [NotNullWhen(true)] out UInt160? scriptHash) { try { @@ -288,7 +289,7 @@ public static Signer SignerFromJToken(JToken? token) return new() { - Account = UInt160.Parse(accountProp.ToObject()), + Account = UInt160.Parse(accountProp.ToObject()!), Scopes = Enum.Parse(scopesProp.ToObject()!), }; } @@ -350,13 +351,13 @@ public static ContractParameter ContractParameterFromJToken(JToken? token) return new ContractParameter { Type = ContractParameterType.Hash160, - Value = UInt160.Parse(valueProp.ToObject()), + Value = UInt160.Parse(valueProp.ToObject()!), }; case ContractParameterType.Hash256: return new ContractParameter { Type = ContractParameterType.Hash256, - Value = UInt256.Parse(valueProp.ToObject()), + Value = UInt256.Parse(valueProp.ToObject()!), }; case ContractParameterType.PublicKey: return new ContractParameter diff --git a/src/Plugins/RestServer/Tokens/NEP11Token.cs b/src/Plugins/RestServer/Tokens/NEP11Token.cs index 6f46a2507e..1d3d454431 100644 --- a/src/Plugins/RestServer/Tokens/NEP11Token.cs +++ b/src/Plugins/RestServer/Tokens/NEP11Token.cs @@ -70,7 +70,7 @@ public NEP11Token( public BigDecimal TotalSupply() { - if (ContractHelper.GetContractMethod(_snapshot, ScriptHash, "totalSupply", 0) == null) + if (ContractHelper.GetContractMethod(_snapshot, ScriptHash, "totalSupply", 0) is null) throw new NotSupportedException(nameof(ScriptHash)); if (ScriptHelper.InvokeMethod(_neoSystem.Settings, _snapshot, ScriptHash, "totalSupply", out var results)) return new(results[0].GetInteger(), Decimals); @@ -79,7 +79,7 @@ public BigDecimal TotalSupply() public BigDecimal BalanceOf(UInt160 owner) { - if (ContractHelper.GetContractMethod(_snapshot, ScriptHash, "balanceOf", 1) == null) + if (ContractHelper.GetContractMethod(_snapshot, ScriptHash, "balanceOf", 1) is null) throw new NotSupportedException(nameof(ScriptHash)); if (ScriptHelper.InvokeMethod(_neoSystem.Settings, _snapshot, ScriptHash, "balanceOf", out var results, owner)) return new(results[0].GetInteger(), Decimals); @@ -90,7 +90,7 @@ public BigDecimal BalanceOf(UInt160 owner, byte[] tokenId) { if (Decimals == 0) throw new InvalidOperationException(); - if (ContractHelper.GetContractMethod(_snapshot, ScriptHash, "balanceOf", 2) == null) + if (ContractHelper.GetContractMethod(_snapshot, ScriptHash, "balanceOf", 2) is null) throw new NotSupportedException(nameof(ScriptHash)); ArgumentNullException.ThrowIfNull(tokenId, nameof(tokenId)); if (tokenId.Length > 64) @@ -102,7 +102,7 @@ public BigDecimal BalanceOf(UInt160 owner, byte[] tokenId) public IEnumerable TokensOf(UInt160 owner) { - if (ContractHelper.GetContractMethod(_snapshot, ScriptHash, "tokensOf", 1) == null) + if (ContractHelper.GetContractMethod(_snapshot, ScriptHash, "tokensOf", 1) is null) throw new NotSupportedException(nameof(ScriptHash)); if (ScriptHelper.InvokeMethod(_neoSystem.Settings, _snapshot, ScriptHash, "tokensOf", out var results, owner)) { @@ -117,7 +117,7 @@ public IEnumerable TokensOf(UInt160 owner) public UInt160[] OwnerOf(byte[] tokenId) { - if (ContractHelper.GetContractMethod(_snapshot, ScriptHash, "ownerOf", 1) == null) + if (ContractHelper.GetContractMethod(_snapshot, ScriptHash, "ownerOf", 1) is null) throw new NotSupportedException(nameof(ScriptHash)); ArgumentNullException.ThrowIfNull(tokenId, nameof(tokenId)); if (tokenId.Length > 64) @@ -146,7 +146,7 @@ public UInt160[] OwnerOf(byte[] tokenId) public IEnumerable Tokens() { - if (ContractHelper.GetContractMethod(_snapshot, ScriptHash, "tokens", 0) == null) + if (ContractHelper.GetContractMethod(_snapshot, ScriptHash, "tokens", 0) is null) throw new NotImplementedException(); if (ScriptHelper.InvokeMethod(_neoSystem.Settings, _snapshot, ScriptHash, "tokens", out var results)) { @@ -162,7 +162,7 @@ public IEnumerable Tokens() public IReadOnlyDictionary? Properties(byte[] tokenId) { ArgumentNullException.ThrowIfNull(tokenId, nameof(tokenId)); - if (ContractHelper.GetContractMethod(_snapshot, ScriptHash, "properties", 1) == null) + if (ContractHelper.GetContractMethod(_snapshot, ScriptHash, "properties", 1) is null) throw new NotImplementedException("no 'properties' with 1 arguments method for NEP-11 contract"); if (tokenId.Length > 64) throw new ArgumentOutOfRangeException(nameof(tokenId)); diff --git a/src/Plugins/RestServer/Tokens/NEP17Token.cs b/src/Plugins/RestServer/Tokens/NEP17Token.cs index 1ebb8fa62b..70c1cdf79d 100644 --- a/src/Plugins/RestServer/Tokens/NEP17Token.cs +++ b/src/Plugins/RestServer/Tokens/NEP17Token.cs @@ -60,7 +60,7 @@ public NEP17Token( public BigDecimal BalanceOf(UInt160 address) { - if (ContractHelper.GetContractMethod(_dataCache, ScriptHash, "balanceOf", 1) == null) + if (ContractHelper.GetContractMethod(_dataCache, ScriptHash, "balanceOf", 1) is null) throw new NotSupportedException(nameof(ScriptHash)); if (ScriptHelper.InvokeMethod(_neoSystem.Settings, _dataCache, ScriptHash, "balanceOf", out var result, address)) { @@ -76,7 +76,7 @@ public BigDecimal BalanceOf(UInt160 address) public BigDecimal TotalSupply() { - if (ContractHelper.GetContractMethod(_dataCache, ScriptHash, "totalSupply", 0) == null) + if (ContractHelper.GetContractMethod(_dataCache, ScriptHash, "totalSupply", 0) is null) throw new NotSupportedException(nameof(ScriptHash)); if (ScriptHelper.InvokeMethod(_neoSystem.Settings, _dataCache, ScriptHash, "totalSupply", out var result)) return new BigDecimal(result[0].GetInteger(), Decimals); diff --git a/src/Plugins/RocksDBStore/Plugins/Storage/RocksDBStore.cs b/src/Plugins/RocksDBStore/Plugins/Storage/RocksDBStore.cs index a4f479685f..cad3b00899 100644 --- a/src/Plugins/RocksDBStore/Plugins/Storage/RocksDBStore.cs +++ b/src/Plugins/RocksDBStore/Plugins/Storage/RocksDBStore.cs @@ -10,6 +10,7 @@ // modifications are permitted. using Neo.Persistence; +using System; namespace Neo.Plugins.Storage { @@ -26,8 +27,9 @@ public RocksDBStore() /// Get store /// /// RocksDbStore - public IStore GetStore(string path) + public IStore GetStore(string? path) { + ArgumentNullException.ThrowIfNull(path); return new Store(path); } } diff --git a/src/Plugins/RpcServer/Diagnostic.cs b/src/Plugins/RpcServer/Diagnostic.cs index 653cc41ac8..30f34b5ebd 100644 --- a/src/Plugins/RpcServer/Diagnostic.cs +++ b/src/Plugins/RpcServer/Diagnostic.cs @@ -28,9 +28,9 @@ public void ContextLoaded(ExecutionContext context) { var state = context.GetState(); if (currentNodeOfInvocationTree is null) - currentNodeOfInvocationTree = InvocationTree.AddRoot(state.ScriptHash); + currentNodeOfInvocationTree = InvocationTree.AddRoot(state.ScriptHash!); else - currentNodeOfInvocationTree = currentNodeOfInvocationTree.AddChild(state.ScriptHash); + currentNodeOfInvocationTree = currentNodeOfInvocationTree.AddChild(state.ScriptHash!); } public void ContextUnloaded(ExecutionContext context) diff --git a/src/Plugins/RpcServer/Result.cs b/src/Plugins/RpcServer/Result.cs index c64c21e30d..f07741b2a3 100644 --- a/src/Plugins/RpcServer/Result.cs +++ b/src/Plugins/RpcServer/Result.cs @@ -12,6 +12,7 @@ #nullable enable using System; +using System.Diagnostics.CodeAnalysis; namespace Neo.Plugins.RpcServer { @@ -49,7 +50,7 @@ public static T Ok_Or(Func function, RpcError err, bool withData = false) /// The return type /// The execution result /// The Rpc exception - public static T NotNull_Or(this T? result, RpcError err) + public static T NotNull_Or([NotNull] this T? result, RpcError err) { if (result == null) throw new RpcException(err); return result; diff --git a/src/Plugins/RpcServer/RpcServer.Blockchain.cs b/src/Plugins/RpcServer/RpcServer.Blockchain.cs index 863d2e77e3..6f091c72b4 100644 --- a/src/Plugins/RpcServer/RpcServer.Blockchain.cs +++ b/src/Plugins/RpcServer/RpcServer.Blockchain.cs @@ -102,7 +102,7 @@ protected internal virtual JToken GetBlock(BlockHashOrIndex blockHashOrIndex, bo { JObject json = block.ToJson(system.Settings); json["confirmations"] = NativeContract.Ledger.CurrentIndex(snapshot) - block.Index + 1; - UInt256 hash = NativeContract.Ledger.GetBlockHash(snapshot, block.Index + 1); + UInt256? hash = NativeContract.Ledger.GetBlockHash(snapshot, block.Index + 1); if (hash != null) json["nextblockhash"] = hash.ToString(); return json; @@ -153,11 +153,8 @@ protected internal virtual JToken GetBlockCount() protected internal virtual JToken GetBlockHash(uint height) { var snapshot = system.StoreView; - if (height <= NativeContract.Ledger.CurrentIndex(snapshot)) - { - return NativeContract.Ledger.GetBlockHash(snapshot, height).ToString(); - } - throw new RpcException(RpcError.UnknownHeight); + return NativeContract.Ledger.GetBlockHash(snapshot, height)?.ToString() + ?? throw new RpcException(RpcError.UnknownHeight); } /// @@ -373,7 +370,7 @@ protected internal virtual JToken GetRawTransaction(UInt256 hash, bool verbose = var json = tx!.ToJson(system.Settings); if (state is not null) { - var block = NativeContract.Ledger.GetTrimmedBlock(snapshot, NativeContract.Ledger.GetBlockHash(snapshot, state.BlockIndex)); + var block = NativeContract.Ledger.GetTrimmedBlock(snapshot, NativeContract.Ledger.GetBlockHash(snapshot, state.BlockIndex)!)!; json["blockhash"] = block.Hash.ToString(); json["confirmations"] = NativeContract.Ledger.CurrentIndex(snapshot) - block.Index + 1; json["blocktime"] = block.Header.Timestamp; @@ -573,7 +570,7 @@ protected internal virtual JToken GetCandidates() byte[] script; using (ScriptBuilder sb = new()) { - script = sb.EmitDynamicCall(NativeContract.NEO.Hash, "getCandidates", null).ToArray(); + script = sb.EmitDynamicCall(NativeContract.NEO.Hash, "getCandidates").ToArray(); } StackItem[] resultstack; try @@ -721,7 +718,7 @@ protected internal virtual JToken GetNativeContracts() var contractStates = NativeContract.Contracts .Select(p => NativeContract.ContractManagement.GetContract(storeView, p.Hash)) .Where(p => p != null) // if not active - .Select(p => p.ToJson()); + .Select(p => p!.ToJson()); return new JArray(contractStates); } } diff --git a/src/Plugins/RpcServer/RpcServer.SmartContract.cs b/src/Plugins/RpcServer/RpcServer.SmartContract.cs index 54e55171ef..6bd01a67fd 100644 --- a/src/Plugins/RpcServer/RpcServer.SmartContract.cs +++ b/src/Plugins/RpcServer/RpcServer.SmartContract.cs @@ -88,7 +88,7 @@ private JObject GetInvokeResult(byte[] script, Signer[]? signers = null, Witness })); if (useDiagnostic) { - var diagnostic = (Diagnostic)session.Engine.Diagnostic; + var diagnostic = (Diagnostic)session.Engine.Diagnostic!; json["diagnostics"] = new JObject() { ["invokedcontracts"] = ToJson(diagnostic.InvocationTree.Root!), @@ -242,7 +242,7 @@ protected internal virtual JToken InvokeFunction(UInt160 scriptHash, string oper byte[] script; using (var sb = new ScriptBuilder()) { - script = sb.EmitDynamicCall(scriptHash, operation, args).ToArray(); + script = sb.EmitDynamicCall(scriptHash, operation, args ?? []).ToArray(); } return GetInvokeResult(script, signers, witnesses, useDiagnostic); } diff --git a/src/Plugins/RpcServer/RpcServer.Wallet.cs b/src/Plugins/RpcServer/RpcServer.Wallet.cs index 1f88fb40e3..77f35ae878 100644 --- a/src/Plugins/RpcServer/RpcServer.Wallet.cs +++ b/src/Plugins/RpcServer/RpcServer.Wallet.cs @@ -34,15 +34,15 @@ partial class RpcServer { private class DummyWallet : Wallet { - public DummyWallet(ProtocolSettings settings) : base(null, settings) { } + public DummyWallet(ProtocolSettings settings) : base(null!, settings) { } public override string Name => ""; public override Version Version => new(); public override bool ChangePassword(string oldPassword, string newPassword) => false; public override bool Contains(UInt160 scriptHash) => false; - public override WalletAccount? CreateAccount(byte[] privateKey) => null; - public override WalletAccount? CreateAccount(Contract contract, KeyPair? key = null) => null; - public override WalletAccount? CreateAccount(UInt160 scriptHash) => null; + public override WalletAccount CreateAccount(byte[] privateKey) => null!; + public override WalletAccount CreateAccount(Contract contract, KeyPair? key = null) => null!; + public override WalletAccount CreateAccount(UInt160 scriptHash) => null!; public override void Delete() { } public override bool DeleteAccount(UInt160 scriptHash) => false; public override WalletAccount? GetAccount(UInt160 scriptHash) => null; @@ -93,7 +93,7 @@ protected internal virtual JToken DumpPrivKey(Address address) { return CheckWallet().GetAccount(address.ScriptHash) .NotNull_Or(RpcError.UnknownAccount.WithData($"{address.ScriptHash}")) - .GetKey() + .GetKey()! .Export(); } @@ -720,7 +720,7 @@ private JObject GetVerificationResult(UInt160 scriptHash, ContractParameter[] ar { Signers = signers ?? [new() { Account = scriptHash }], Attributes = [], - Witnesses = witnesses, + Witnesses = witnesses ?? [], Script = new[] { (byte)OpCode.RET } }; diff --git a/src/Plugins/RpcServer/Session.cs b/src/Plugins/RpcServer/Session.cs index 41fd92edfb..0d88821391 100644 --- a/src/Plugins/RpcServer/Session.cs +++ b/src/Plugins/RpcServer/Session.cs @@ -38,7 +38,7 @@ public Session(NeoSystem system, byte[] script, Signer[]? signers, Witness[]? wi Signers = signers, Attributes = [], Script = script, - Witnesses = witnesses + Witnesses = witnesses ?? [] }; Engine = ApplicationEngine.Run(script, Snapshot, container: tx, settings: system.Settings, gas: datoshi, diagnostic: diagnostic); ResetExpiration(); diff --git a/src/Plugins/SQLiteWallet/SQLiteWalletFactory.cs b/src/Plugins/SQLiteWallet/SQLiteWalletFactory.cs index b4dcb5b163..95826b78ff 100644 --- a/src/Plugins/SQLiteWallet/SQLiteWalletFactory.cs +++ b/src/Plugins/SQLiteWallet/SQLiteWalletFactory.cs @@ -29,7 +29,7 @@ public bool Handle(string path) return GetExtension(path).Equals(".db3", StringComparison.InvariantCultureIgnoreCase); } - public Wallet CreateWallet(string name, string path, string password, ProtocolSettings settings) + public Wallet CreateWallet(string? name, string path, string password, ProtocolSettings settings) { return SQLiteWallet.Create(path, password, settings); } diff --git a/src/Plugins/SignClient/SignClient.cs b/src/Plugins/SignClient/SignClient.cs index fd37f02095..e08dcb2e55 100644 --- a/src/Plugins/SignClient/SignClient.cs +++ b/src/Plugins/SignClient/SignClient.cs @@ -210,7 +210,7 @@ internal Witness[] SignContext(ContractParametersContext context, IEnumerable transfers, ref uint transferIndex) + private void HandleNotificationNep11(IVerifiable? scriptContainer, UInt160 asset, Array stateItems, List transfers, ref uint transferIndex) { if (stateItems.Count != 4) return; var transferRecord = GetTransferRecord(asset, stateItems); @@ -277,7 +277,7 @@ public JToken GetNep11Balances(Address address) var engine = ApplicationEngine.Run(script.ToArray(), _neoSystem.StoreView, settings: _neoSystem.Settings); var symbol = engine.ResultStack.Pop().GetString(); var decimals = engine.ResultStack.Pop().GetInteger(); - var name = NativeContract.ContractManagement.GetContract(_neoSystem.StoreView, key).Manifest.Name; + var name = NativeContract.ContractManagement.GetContract(_neoSystem.StoreView, key)!.Manifest.Name; balances.Add(new JObject { diff --git a/src/Plugins/TokensTracker/Trackers/NEP-17/Nep17Tracker.cs b/src/Plugins/TokensTracker/Trackers/NEP-17/Nep17Tracker.cs index 679d41cc7b..be3bd66d3c 100644 --- a/src/Plugins/TokensTracker/Trackers/NEP-17/Nep17Tracker.cs +++ b/src/Plugins/TokensTracker/Trackers/NEP-17/Nep17Tracker.cs @@ -91,7 +91,7 @@ public override void OnPersist(NeoSystem system, Block block, DataCache snapshot } } - private void HandleNotificationNep17(IVerifiable scriptContainer, UInt160 asset, Array stateItems, HashSet balanceChangeRecords, ref uint transferIndex) + private void HandleNotificationNep17(IVerifiable? scriptContainer, UInt160 asset, Array stateItems, HashSet balanceChangeRecords, ref uint transferIndex) { if (stateItems.Count != 3) return; var transferRecord = GetTransferRecord(asset, stateItems); @@ -192,7 +192,7 @@ public JToken GetNep17Balances(Address address) var engine = ApplicationEngine.Run(script.ToArray(), _neoSystem.StoreView, settings: _neoSystem.Settings); var symbol = engine.ResultStack.Pop().GetString(); var decimals = engine.ResultStack.Pop().GetInteger(); - var name = NativeContract.ContractManagement.GetContract(_neoSystem.StoreView, key.AssetScriptHash).Manifest.Name; + var name = NativeContract.ContractManagement.GetContract(_neoSystem.StoreView, key.AssetScriptHash)!.Manifest.Name; balances.Add(new JObject { diff --git a/src/RpcClient/TransactionManagerFactory.cs b/src/RpcClient/TransactionManagerFactory.cs index db8466cab4..829fe40d2d 100644 --- a/src/RpcClient/TransactionManagerFactory.cs +++ b/src/RpcClient/TransactionManagerFactory.cs @@ -64,6 +64,7 @@ public async Task MakeTransactionAsync(ReadOnlyMemory ValidUntilBlock = blockCount - 1 + rpcClient.protocolSettings.MaxValidUntilBlockIncrement, SystemFee = systemFee, Attributes = attributes ?? Array.Empty(), + Witnesses = [] }; return new TransactionManager(tx, rpcClient); diff --git a/tests/Neo.Plugins.ApplicationLogs.Tests/UT_LogReader.cs b/tests/Neo.Plugins.ApplicationLogs.Tests/UT_LogReader.cs index eef191db79..22aa15f1d5 100644 --- a/tests/Neo.Plugins.ApplicationLogs.Tests/UT_LogReader.cs +++ b/tests/Neo.Plugins.ApplicationLogs.Tests/UT_LogReader.cs @@ -82,6 +82,7 @@ public NeoSystemFixture() Script = Convert.FromBase64String(NeoTransferScript), NetworkFee = 1000_0000, SystemFee = 1000_0000, + Witnesses = [] } ]; byte[] signature = txs[0].Sign(_walletAccount.GetKey(), ApplicationLogsSettings.Default.Network); @@ -100,6 +101,7 @@ public NeoSystemFixture() Timestamp = _neoSystem.GenesisBlock.Timestamp + 15_000, Index = 1, NextConsensus = _neoSystem.GenesisBlock.NextConsensus, + Witness = null! }, Transactions = txs, }; diff --git a/tests/Neo.Plugins.DBFTPlugin.Tests/UT_ConsensusService.cs b/tests/Neo.Plugins.DBFTPlugin.Tests/UT_ConsensusService.cs index 73bdbb8f49..627baabd93 100644 --- a/tests/Neo.Plugins.DBFTPlugin.Tests/UT_ConsensusService.cs +++ b/tests/Neo.Plugins.DBFTPlugin.Tests/UT_ConsensusService.cs @@ -13,21 +13,15 @@ using Akka.TestKit; using Akka.TestKit.MsTest; using Microsoft.VisualStudio.TestTools.UnitTesting; - -using Neo.Cryptography.ECC; using Neo.Extensions; -using Neo.IO; using Neo.Ledger; -using Neo.Network.P2P; using Neo.Network.P2P.Payloads; using Neo.Persistence.Providers; using Neo.Plugins.DBFTPlugin.Consensus; using Neo.Plugins.DBFTPlugin.Messages; using Neo.SmartContract; using Neo.VM; -using Neo.Wallets; using System; -using System.Collections.Generic; using System.Linq; using System.Threading; @@ -156,7 +150,7 @@ public void TestConsensusServiceReceivesBlockchainMessages() }; // Act - consensusService.Tell(new Blockchain.PersistCompleted { Block = block }); + consensusService.Tell(new Blockchain.PersistCompleted(block)); // Assert - The service should handle the message without throwing ExpectNoMsg(TimeSpan.FromMilliseconds(100), cancellationToken: CancellationToken.None); diff --git a/tests/Neo.Plugins.DBFTPlugin.Tests/UT_DBFT_Core.cs b/tests/Neo.Plugins.DBFTPlugin.Tests/UT_DBFT_Core.cs index d25e0db366..e6701c5263 100644 --- a/tests/Neo.Plugins.DBFTPlugin.Tests/UT_DBFT_Core.cs +++ b/tests/Neo.Plugins.DBFTPlugin.Tests/UT_DBFT_Core.cs @@ -13,22 +13,13 @@ using Akka.TestKit; using Akka.TestKit.MsTest; using Microsoft.VisualStudio.TestTools.UnitTesting; - -using Neo.Cryptography.ECC; -using Neo.Extensions; -using Neo.IO; using Neo.Ledger; -using Neo.Network.P2P; using Neo.Network.P2P.Payloads; using Neo.Persistence.Providers; using Neo.Plugins.DBFTPlugin.Consensus; -using Neo.Plugins.DBFTPlugin.Messages; -using Neo.Plugins.DBFTPlugin.Types; using Neo.SmartContract; using Neo.VM; -using Neo.Wallets; using System; -using System.Collections.Generic; using System.Linq; using System.Threading; @@ -116,7 +107,7 @@ public void TestBasicConsensusFlow() var genesisBlock = neoSystem.GenesisBlock; foreach (var service in consensusServices) { - service.Tell(new Blockchain.PersistCompleted { Block = genesisBlock }); + service.Tell(new Blockchain.PersistCompleted(genesisBlock)); } // Assert - Services should start consensus without throwing @@ -146,7 +137,7 @@ public void TestPrimarySelection() // Simulate block persistence to trigger consensus var genesisBlock = neoSystem.GenesisBlock; - primaryService.Tell(new Blockchain.PersistCompleted { Block = genesisBlock }); + primaryService.Tell(new Blockchain.PersistCompleted(genesisBlock)); // Assert - Primary should start consensus process ExpectNoMsg(TimeSpan.FromMilliseconds(500), cancellationToken: CancellationToken.None); @@ -187,7 +178,7 @@ public void TestMultipleRounds() Transactions = Array.Empty() }; - consensusService.Tell(new Blockchain.PersistCompleted { Block = block }); + consensusService.Tell(new Blockchain.PersistCompleted(block)); // Wait between rounds ExpectNoMsg(TimeSpan.FromMilliseconds(100), cancellationToken: CancellationToken.None); diff --git a/tests/Neo.Plugins.DBFTPlugin.Tests/UT_DBFT_Integration.cs b/tests/Neo.Plugins.DBFTPlugin.Tests/UT_DBFT_Integration.cs index d53aa70cce..e4a6f9a5f5 100644 --- a/tests/Neo.Plugins.DBFTPlugin.Tests/UT_DBFT_Integration.cs +++ b/tests/Neo.Plugins.DBFTPlugin.Tests/UT_DBFT_Integration.cs @@ -13,23 +13,13 @@ using Akka.TestKit; using Akka.TestKit.MsTest; using Microsoft.VisualStudio.TestTools.UnitTesting; - -using Neo.Cryptography.ECC; -using Neo.IO; using Neo.Ledger; -using Neo.Network.P2P; using Neo.Network.P2P.Payloads; using Neo.Persistence.Providers; using Neo.Plugins.DBFTPlugin.Consensus; -using Neo.Plugins.DBFTPlugin.Messages; -using Neo.SmartContract; -using Neo.VM; -using Neo.Wallets; using System; -using System.Collections.Generic; using System.Linq; using System.Threading; -using System.Threading.Tasks; namespace Neo.Plugins.DBFTPlugin.Tests { @@ -128,7 +118,7 @@ public void TestFullConsensusRound() var genesisBlock = neoSystem.GenesisBlock; foreach (var service in consensusServices) { - service.Tell(new Blockchain.PersistCompleted { Block = genesisBlock }); + service.Tell(new Blockchain.PersistCompleted(genesisBlock)); } // Assert - Wait for consensus messages to be exchanged @@ -161,14 +151,14 @@ public void TestConsensusWithViewChange() var genesisBlock = neoSystem.GenesisBlock; for (int i = 1; i < ValidatorCount; i++) // Skip primary { - consensusServices[i].Tell(new Blockchain.PersistCompleted { Block = genesisBlock }); + consensusServices[i].Tell(new Blockchain.PersistCompleted(genesisBlock)); } // Wait for timeout and view change ExpectNoMsg(TimeSpan.FromSeconds(3), cancellationToken: CancellationToken.None); // Now start the new primary (index 1) after view change - consensusServices[0].Tell(new Blockchain.PersistCompleted { Block = genesisBlock }); + consensusServices[0].Tell(new Blockchain.PersistCompleted(genesisBlock)); // Assert - Consensus should eventually succeed with new primary ExpectNoMsg(TimeSpan.FromSeconds(2), cancellationToken: CancellationToken.None); @@ -199,7 +189,7 @@ public void TestConsensusWithByzantineFailures() var genesisBlock = neoSystem.GenesisBlock; for (int i = 0; i < honestValidators; i++) { - consensusServices[i].Tell(new Blockchain.PersistCompleted { Block = genesisBlock }); + consensusServices[i].Tell(new Blockchain.PersistCompleted(genesisBlock)); } // Assert - Consensus should succeed with 3 honest validators out of 4 @@ -232,14 +222,14 @@ public void TestConsensusRecovery() // Start consensus with first 3 validators for (int i = 0; i < ValidatorCount - 1; i++) { - consensusServices[i].Tell(new Blockchain.PersistCompleted { Block = genesisBlock }); + consensusServices[i].Tell(new Blockchain.PersistCompleted(genesisBlock)); } // Wait a bit for consensus to start ExpectNoMsg(TimeSpan.FromMilliseconds(500), cancellationToken: CancellationToken.None); // Late validator joins and should request recovery - consensusServices[ValidatorCount - 1].Tell(new Blockchain.PersistCompleted { Block = genesisBlock }); + consensusServices[ValidatorCount - 1].Tell(new Blockchain.PersistCompleted(genesisBlock)); // Assert - Recovery should allow late validator to catch up ExpectNoMsg(TimeSpan.FromSeconds(2), cancellationToken: CancellationToken.None); diff --git a/tests/Neo.Plugins.OracleService.Tests/E2E_Https.cs b/tests/Neo.Plugins.OracleService.Tests/E2E_Https.cs index f7873e379b..51e2183b39 100644 --- a/tests/Neo.Plugins.OracleService.Tests/E2E_Https.cs +++ b/tests/Neo.Plugins.OracleService.Tests/E2E_Https.cs @@ -67,6 +67,7 @@ public void TestE2EHttps() Script = script, NetworkFee = 1000_0000, SystemFee = 2_0000_0000, + Witnesses = [] } ]; byte[] signature = txs[0].Sign(s_walletAccount.GetKey(), settings.Network); @@ -81,9 +82,11 @@ public void TestE2EHttps() { Version = 0, PrevHash = s_theNeoSystem.GenesisBlock.Hash, + MerkleRoot = null!, Timestamp = s_theNeoSystem.GenesisBlock.Timestamp + 15_000, Index = 1, NextConsensus = s_theNeoSystem.GenesisBlock.NextConsensus, + Witness = null! }, Transactions = txs, }; diff --git a/tests/Neo.Plugins.OracleService.Tests/UT_OracleService.cs b/tests/Neo.Plugins.OracleService.Tests/UT_OracleService.cs index 64178d9105..b7881887e4 100644 --- a/tests/Neo.Plugins.OracleService.Tests/UT_OracleService.cs +++ b/tests/Neo.Plugins.OracleService.Tests/UT_OracleService.cs @@ -71,7 +71,13 @@ public void TestCreateOracleResponseTx() snapshotCache.Add(NativeContract.Ledger.CreateStorageKey(Prefix_Transaction, request.OriginalTxid), new(new TransactionState() { BlockIndex = 1, - Transaction = new() { ValidUntilBlock = 1 } + Transaction = new() + { + Signers = [], + Attributes = [], + ValidUntilBlock = 1, + Witnesses = [] + } })); OracleResponse response = new() { Id = 1, Code = OracleResponseCode.Success, Result = new byte[] { 0x00 } }; diff --git a/tests/Neo.Plugins.SignClient.Tests/UT_SignClient.cs b/tests/Neo.Plugins.SignClient.Tests/UT_SignClient.cs index 44bd00cda2..e473b7c9e0 100644 --- a/tests/Neo.Plugins.SignClient.Tests/UT_SignClient.cs +++ b/tests/Neo.Plugins.SignClient.Tests/UT_SignClient.cs @@ -89,7 +89,7 @@ private static SignClient NewClient(Block? block, ExtensiblePayload? payload) { if (req.PublicKey.ToByteArray().ToHexString() == PublicKey) { - var sign = Crypto.Sign(block.GetSignData(s_testNetwork), PrivateKey.HexToBytes(), ECCurve.Secp256r1); + var sign = Crypto.Sign(block!.GetSignData(s_testNetwork), PrivateKey.HexToBytes(), ECCurve.Secp256r1); return new() { Signature = ByteString.CopyFrom(sign) }; } throw new RpcException(new Status(StatusCode.NotFound, "no such account")); @@ -113,7 +113,7 @@ private static SignClient NewClient(Block? block, ExtensiblePayload? payload) var contract = new AccountContract() { Script = ByteString.CopyFrom(script) }; contract.Parameters.Add((uint)ContractParameterType.Signature); - var sign = Crypto.Sign(payload.GetSignData(s_testNetwork), PrivateKey.HexToBytes(), ECCurve.Secp256r1); + var sign = Crypto.Sign(payload!.GetSignData(s_testNetwork), PrivateKey.HexToBytes(), ECCurve.Secp256r1); var signs = new AccountSigns() { Status = AccountStatus.Single, Contract = contract }; signs.Signs.Add(new AccountSign() { @@ -170,6 +170,7 @@ public void TestSignExtensiblePayload() ValidBlockEnd = 100, Sender = signer, Data = new byte[] { 1, 2, 3 }, + Witness = null! }; using var signClient = NewClient(null, payload); using var store = new MemoryStore(); diff --git a/tests/Neo.RpcClient.Tests/UT_ContractClient.cs b/tests/Neo.RpcClient.Tests/UT_ContractClient.cs index 6ebda13b85..840daf4983 100644 --- a/tests/Neo.RpcClient.Tests/UT_ContractClient.cs +++ b/tests/Neo.RpcClient.Tests/UT_ContractClient.cs @@ -54,6 +54,7 @@ public async Task TestDeployContract() byte[] script; var manifest = new ContractManifest() { + Name = "", Permissions = [ContractPermission.DefaultPermission], Abi = new ContractAbi() { Events = [], Methods = [] }, Groups = [], diff --git a/tests/Neo.RpcClient.Tests/UT_TransactionManager.cs b/tests/Neo.RpcClient.Tests/UT_TransactionManager.cs index 51438d8b24..a49069ee2f 100644 --- a/tests/Neo.RpcClient.Tests/UT_TransactionManager.cs +++ b/tests/Neo.RpcClient.Tests/UT_TransactionManager.cs @@ -181,7 +181,6 @@ await txManager // duplicate sign should not add new witness await ThrowsAsync(async () => await txManager.AddSignature(keyPair1).SignAsync()); - Assert.IsNull(txManager.Tx.Witnesses); // throw exception when the KeyPair is wrong await ThrowsAsync(async () => await txManager.AddSignature(keyPair2).SignAsync()); diff --git a/tests/Neo.UnitTests/Builders/UT_SignerBuilder.cs b/tests/Neo.UnitTests/Builders/UT_SignerBuilder.cs index 6b4c5a1490..f0d1daebdc 100644 --- a/tests/Neo.UnitTests/Builders/UT_SignerBuilder.cs +++ b/tests/Neo.UnitTests/Builders/UT_SignerBuilder.cs @@ -20,18 +20,10 @@ namespace Neo.UnitTests.Builders [TestClass] public class UT_SignerBuilder { - [TestMethod] - public void TestCreateEmpty() - { - var sb = SignerBuilder.CreateEmpty(); - Assert.IsNotNull(sb); - } - [TestMethod] public void TestAccount() { - var signer = SignerBuilder.CreateEmpty() - .Account(UInt160.Zero) + var signer = SignerBuilder.Create(UInt160.Zero) .Build(); Assert.IsNotNull(signer); @@ -41,11 +33,10 @@ public void TestAccount() [TestMethod] public void TestAllowContract() { - var signer = SignerBuilder.CreateEmpty() + var signer = SignerBuilder.Create(UInt160.Zero) .AllowContract(UInt160.Zero) .Build(); - Assert.IsNotNull(signer); Assert.HasCount(1, signer.AllowedContracts); Assert.AreEqual(UInt160.Zero, signer.AllowedContracts[0]); } @@ -54,11 +45,10 @@ public void TestAllowContract() public void TestAllowGroup() { var myPublicKey = ECPoint.Parse("021821807f923a3da004fb73871509d7635bcc05f41edef2a3ca5c941d8bbc1231", ECCurve.Secp256r1); - var signer = SignerBuilder.CreateEmpty() + var signer = SignerBuilder.Create(UInt160.Zero) .AllowGroup(myPublicKey) .Build(); - Assert.IsNotNull(signer); Assert.HasCount(1, signer.AllowedGroups); Assert.AreEqual(myPublicKey, signer.AllowedGroups[0]); } @@ -66,18 +56,17 @@ public void TestAllowGroup() [TestMethod] public void TestAddWitnessScope() { - var signer = SignerBuilder.CreateEmpty() + var signer = SignerBuilder.Create(UInt160.Zero) .AddWitnessScope(WitnessScope.Global) .Build(); - Assert.IsNotNull(signer); Assert.AreEqual(WitnessScope.Global, signer.Scopes); } [TestMethod] public void TestAddWitnessRule() { - var signer = SignerBuilder.CreateEmpty() + var signer = SignerBuilder.Create(UInt160.Zero) .AddWitnessRule(WitnessRuleAction.Allow, rb => { rb.AddCondition(cb => @@ -87,7 +76,6 @@ public void TestAddWitnessRule() }) .Build(); - Assert.IsNotNull(signer); Assert.HasCount(1, signer.Rules); Assert.AreEqual(WitnessRuleAction.Allow, signer.Rules[0].Action); Assert.IsInstanceOfType(signer.Rules[0].Condition); diff --git a/tests/Neo.UnitTests/Builders/UT_TransactionAttributesBuilder.cs b/tests/Neo.UnitTests/Builders/UT_TransactionAttributesBuilder.cs index bb871d07f7..e96a6b2ce4 100644 --- a/tests/Neo.UnitTests/Builders/UT_TransactionAttributesBuilder.cs +++ b/tests/Neo.UnitTests/Builders/UT_TransactionAttributesBuilder.cs @@ -30,7 +30,7 @@ public void TestCreateEmpty() public void TestConflict() { var attr = TransactionAttributesBuilder.CreateEmpty() - .AddConflict(c => c.Hash = UInt256.Zero) + .AddConflict(UInt256.Zero) .Build(); Assert.IsNotNull(attr); diff --git a/tests/Neo.UnitTests/Builders/UT_TransactionBuilder.cs b/tests/Neo.UnitTests/Builders/UT_TransactionBuilder.cs index 6ccab7428f..2e63b8045f 100644 --- a/tests/Neo.UnitTests/Builders/UT_TransactionBuilder.cs +++ b/tests/Neo.UnitTests/Builders/UT_TransactionBuilder.cs @@ -161,9 +161,8 @@ public void TestSigner() var expectedContractHash = UInt160.Zero; var tx = TransactionBuilder.CreateEmpty() - .AddSigner((sb, tx) => + .AddSigner(expectedContractHash, (sb, tx) => { - sb.Account(expectedContractHash); sb.AllowContract(expectedContractHash); sb.AllowGroup(expectedPublicKey); sb.AddWitnessScope(WitnessScope.WitnessRules); @@ -184,7 +183,7 @@ public void TestSigner() Assert.AreEqual(expectedContractHash, tx.Signers[0].AllowedContracts[0]); Assert.HasCount(1, tx.Signers[0].AllowedGroups); Assert.AreEqual(expectedPublicKey, tx.Signers[0].AllowedGroups[0]); - Assert.AreEqual(WitnessScope.WitnessRules, tx.Signers[0].Scopes); + Assert.AreEqual(WitnessScope.CustomContracts | WitnessScope.CustomGroups | WitnessScope.WitnessRules, tx.Signers[0].Scopes); Assert.HasCount(1, tx.Signers[0].Rules); Assert.AreEqual(WitnessRuleAction.Deny, tx.Signers[0].Rules[0].Action); Assert.IsNotNull(tx.Signers[0].Rules[0].Condition); diff --git a/tests/Neo.UnitTests/Extensions/NativeContractExtensions.cs b/tests/Neo.UnitTests/Extensions/NativeContractExtensions.cs index 789885a051..2f0862c7f1 100644 --- a/tests/Neo.UnitTests/Extensions/NativeContractExtensions.cs +++ b/tests/Neo.UnitTests/Extensions/NativeContractExtensions.cs @@ -17,6 +17,7 @@ using Neo.VM; using Neo.VM.Types; using System; +using System.Runtime.CompilerServices; namespace Neo.UnitTests.Extensions { @@ -38,7 +39,7 @@ public static ContractState DeployContract(this DataCache snapshot, UInt160 send script.EmitDynamicCall(NativeContract.ContractManagement.Hash, "deploy", nefFile, manifest, null); var engine = ApplicationEngine.Create(TriggerType.Application, - sender != null ? new Transaction() { Signers = [new() { Account = sender }], Attributes = [] } : null, + sender != null ? new Transaction() { Signers = [new() { Account = sender }], Attributes = [], Witnesses = null! } : null, snapshot, settings: TestProtocolSettings.Default, gas: datoshi); engine.LoadScript(script.ToArray()); @@ -49,7 +50,7 @@ public static ContractState DeployContract(this DataCache snapshot, UInt160 send throw exception ?? new InvalidOperationException(); } - var ret = new ContractState(); + var ret = (ContractState)RuntimeHelpers.GetUninitializedObject(typeof(ContractState)); ((IInteroperable)ret).FromStackItem(engine.ResultStack.Pop()); return ret; } diff --git a/tests/Neo.UnitTests/Extensions/Nep17NativeContractExtensions.cs b/tests/Neo.UnitTests/Extensions/Nep17NativeContractExtensions.cs index e2b9b89f9f..9519404124 100644 --- a/tests/Neo.UnitTests/Extensions/Nep17NativeContractExtensions.cs +++ b/tests/Neo.UnitTests/Extensions/Nep17NativeContractExtensions.cs @@ -79,7 +79,7 @@ public static bool Transfer(this NativeContract contract, DataCache snapshot, by public static bool TransferWithTransaction(this NativeContract contract, DataCache snapshot, byte[] from, byte[] to, BigInteger amount, bool signFrom, Block persistingBlock, object data) { using var engine = ApplicationEngine.Create(TriggerType.Application, - new Transaction() { Signers = [new() { Account = signFrom ? new(from) : null, Scopes = WitnessScope.Global }], Attributes = [] }, + new Transaction() { Signers = [new() { Account = signFrom ? new(from) : null, Scopes = WitnessScope.Global }], Attributes = [], Witnesses = null! }, snapshot, persistingBlock, settings: TestProtocolSettings.Default); using var script = new ScriptBuilder(); diff --git a/tests/Neo.UnitTests/GasTests/GasFixturesTests.cs b/tests/Neo.UnitTests/GasTests/GasFixturesTests.cs index cbecc6d990..5ff674dfb2 100644 --- a/tests/Neo.UnitTests/GasTests/GasFixturesTests.cs +++ b/tests/Neo.UnitTests/GasTests/GasFixturesTests.cs @@ -62,7 +62,18 @@ public static void AssertFixture(GasTestFixture fixture, DataCache snapshot) } } - var persistingBlock = new Block { Header = new Header() { Index = 1 } }; + var persistingBlock = new Block + { + Header = new Header + { + PrevHash = UInt256.Zero, + MerkleRoot = null!, + Index = 1, + NextConsensus = null!, + Witness = null! + }, + Transactions = null! + }; // Signature diff --git a/tests/Neo.UnitTests/Ledger/UT_HeaderCache.cs b/tests/Neo.UnitTests/Ledger/UT_HeaderCache.cs index eb9b22414c..9ea7d3b890 100644 --- a/tests/Neo.UnitTests/Ledger/UT_HeaderCache.cs +++ b/tests/Neo.UnitTests/Ledger/UT_HeaderCache.cs @@ -24,7 +24,11 @@ public void TestHeaderCache() var cache = new HeaderCache(); var header = new Header { - Index = 1 + PrevHash = UInt256.Zero, + MerkleRoot = null!, + Index = 1, + NextConsensus = null!, + Witness = null! }; cache.Add(header); @@ -76,7 +80,14 @@ public void TestHeaderCache_Limit() // Fill the cache for (uint i = 0; i < capacity; i++) { - cache.Add(new Header { Index = i }); + cache.Add(new Header + { + PrevHash = UInt256.Zero, + MerkleRoot = null!, + Index = i, + NextConsensus = null!, + Witness = null! + }); } Assert.AreEqual((int)capacity, cache.Count); @@ -84,7 +95,14 @@ public void TestHeaderCache_Limit() Assert.AreEqual(capacity - 1, cache.Last.Index); // Try adding one more - cache.Add(new Header { Index = capacity }); + cache.Add(new Header + { + PrevHash = null!, + MerkleRoot = null!, + Index = capacity, + NextConsensus = null!, + Witness = null! + }); // Verify count did not increase and last item remains the same Assert.AreEqual((int)capacity, cache.Count); diff --git a/tests/Neo.UnitTests/Ledger/UT_MemoryPool.cs b/tests/Neo.UnitTests/Ledger/UT_MemoryPool.cs index e156c4299a..d29647a13b 100644 --- a/tests/Neo.UnitTests/Ledger/UT_MemoryPool.cs +++ b/tests/Neo.UnitTests/Ledger/UT_MemoryPool.cs @@ -167,7 +167,13 @@ public void BlockPersistMovesTxToUnverifiedAndReverification() var block = new Block { - Header = new Header(), + Header = new Header + { + PrevHash = null!, + MerkleRoot = null!, + NextConsensus = null!, + Witness = null! + }, Transactions = _unit.GetSortedVerifiedTransactions(10) .Concat(_unit.GetSortedVerifiedTransactions(5)).ToArray() }; @@ -218,7 +224,13 @@ public async Task BlockPersistAndReverificationWillAbandonTxAsBalanceTransfered( var block = new Block { - Header = new Header(), + Header = new Header + { + PrevHash = null!, + MerkleRoot = null!, + NextConsensus = null!, + Witness = null! + }, Transactions = _unit.GetSortedVerifiedTransactions(10) }; @@ -290,7 +302,13 @@ public async Task UpdatePoolForBlockPersisted_RemoveBlockConflicts() // Act: persist block and reverify all mempooled txs. var block = new Block { - Header = new Header(), + Header = new Header + { + PrevHash = null!, + MerkleRoot = null!, + NextConsensus = null!, + Witness = null! + }, Transactions = new Transaction[] { tx1, tx2, tx3, tx4, tx5, tx6 }, }; _unit.UpdatePoolForBlockPersisted(block, engine.SnapshotCache); @@ -441,7 +459,13 @@ public async Task TryRemoveVerified_RemoveVerifiedTxWithConflicts() var tx1 = CreateTransactionWithFeeAndBalanceVerify(txFee); // in-block tx1 doesn't conflict with anyone and is aimed to trigger reverification var block = new Block { - Header = new Header(), + Header = new Header + { + PrevHash = null!, + MerkleRoot = null!, + NextConsensus = null!, + Witness = null! + }, Transactions = new Transaction[] { tx1 }, }; _unit.UpdatePoolForBlockPersisted(block, engine.SnapshotCache); @@ -485,7 +509,13 @@ public void VerifySortOrderAndThatHighetFeeTransactionsAreReverifiedFirst() // move all to unverified var block = new Block { - Header = new Header(), + Header = new Header + { + PrevHash = null!, + MerkleRoot = null!, + NextConsensus = null!, + Witness = null! + }, Transactions = Array.Empty() }; _unit.UpdatePoolForBlockPersisted(block, GetSnapshot()); @@ -510,7 +540,13 @@ public void VerifySortOrderAndThatHighetFeeTransactionsAreReverifiedFirst() Assert.AreEqual(maxTransaction, verifiedTxs[0]); var blockWith2Tx = new Block { - Header = new Header(), + Header = new Header + { + PrevHash = null!, + MerkleRoot = null!, + NextConsensus = null!, + Witness = null! + }, Transactions = new[] { maxTransaction, minTransaction } }; // verify and remove the 2 transactions from the verified pool @@ -553,7 +589,13 @@ public void CapacityTestWithUnverifiedHighProirtyTransactions() // move all to unverified var block = new Block { - Header = new Header(), + Header = new Header + { + PrevHash = null!, + MerkleRoot = null!, + NextConsensus = null!, + Witness = null! + }, Transactions = Array.Empty() }; _unit.UpdatePoolForBlockPersisted(block, GetSnapshot()); @@ -719,7 +761,13 @@ public void TestUpdatePoolForBlockPersisted() var block = new Block { - Header = new Header(), + Header = new Header + { + PrevHash = null!, + MerkleRoot = null!, + NextConsensus = null!, + Witness = null! + }, Transactions = transactions }; diff --git a/tests/Neo.UnitTests/Ledger/UT_TrimmedBlock.cs b/tests/Neo.UnitTests/Ledger/UT_TrimmedBlock.cs index f22968cdb3..69d8a38545 100644 --- a/tests/Neo.UnitTests/Ledger/UT_TrimmedBlock.cs +++ b/tests/Neo.UnitTests/Ledger/UT_TrimmedBlock.cs @@ -18,6 +18,7 @@ using Neo.VM; using System; using System.IO; +using System.Runtime.CompilerServices; namespace Neo.UnitTests.Ledger { @@ -124,7 +125,7 @@ public void TestDeserialize() { TrimmedBlock tblock = GetTrimmedBlockWithNoTransaction(); tblock.Hashes = new UInt256[] { TestUtils.GetTransaction(UInt160.Zero).Hash }; - var newBlock = new TrimmedBlock(); + var newBlock = (TrimmedBlock)RuntimeHelpers.GetUninitializedObject(typeof(TrimmedBlock)); using (MemoryStream ms = new(1024)) using (BinaryWriter writer = new(ms)) { diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Block.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Block.cs index dd5fb9dc4e..0ee9bda43e 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Block.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Block.cs @@ -17,6 +17,7 @@ using Neo.SmartContract; using Neo.SmartContract.Native; using System; +using System.Runtime.CompilerServices; namespace Neo.UnitTests.Network.P2P.Payloads { @@ -35,20 +36,23 @@ private static ApplicationEngine GetEngine(bool hasContainer = false, bool hasSn var system = TestBlockchain.GetSystem(); var tx = hasContainer ? TestUtils.GetTransaction(UInt160.Zero) : null; var snapshotCache = hasSnapshot ? system.GetTestSnapshotCache() : null; - var block = hasBlock ? new Block { Header = new Header() } : null; + var block = hasBlock ? new Block + { + Header = new Header + { + PrevHash = null!, + MerkleRoot = null!, + NextConsensus = null!, + Witness = null! + }, + Transactions = null! + } : null; var engine = ApplicationEngine.Create(TriggerType.Application, tx, snapshotCache, block, system.Settings, gas: gas); if (addScript) engine.LoadScript(new byte[] { 0x01 }); return engine; } - [TestMethod] - public void Transactions_Get() - { - var uut = new Block(); - Assert.IsNull(uut.Transactions); - } - [TestMethod] public void Header_Get() { @@ -113,7 +117,7 @@ public void Deserialize() [TestMethod] public void Equals_SameObj() { - var uut = new Block(); + var uut = (Block)RuntimeHelpers.GetUninitializedObject(typeof(Block)); Assert.IsTrue(uut.Equals(uut)); var obj = uut as object; @@ -140,7 +144,7 @@ public void Equals_DiffObj() [TestMethod] public void Equals_Null() { - var uut = new Block(); + var uut = (Block)RuntimeHelpers.GetUninitializedObject(typeof(Block)); Assert.IsFalse(uut.Equals(null)); } @@ -185,7 +189,11 @@ public void ToJson() [TestMethod] public void Witness() { - IVerifiable item = new Block() { Header = new(), }; + IVerifiable item = new Block() + { + Header = (Header)RuntimeHelpers.GetUninitializedObject(typeof(Header)), + Transactions = [] + }; Assert.HasCount(1, item.Witnesses); void Actual() => item.Witnesses = null; Assert.ThrowsExactly(Actual); diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs index bcf71ebc7e..d842b0e5be 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_ExtensiblePayload.cs @@ -15,6 +15,7 @@ using Neo.SmartContract; using Neo.VM; using System; +using System.Runtime.CompilerServices; namespace Neo.UnitTests.Network.P2P.Payloads { @@ -66,7 +67,7 @@ public void DeserializeAndSerialize() [TestMethod] public void Witness() { - IVerifiable item = new ExtensiblePayload(); + IVerifiable item = (ExtensiblePayload)RuntimeHelpers.GetUninitializedObject(typeof(ExtensiblePayload)); Action actual = () => item.Witnesses = null; Assert.ThrowsExactly(actual); diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Header.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Header.cs index 8a736ccde9..db3b95dbd7 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Header.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Header.cs @@ -15,6 +15,7 @@ using Neo.Network.P2P.Payloads; using Neo.SmartContract.Native; using System; +using System.Runtime.CompilerServices; namespace Neo.UnitTests.Network.P2P.Payloads { @@ -87,13 +88,6 @@ public void Deserialize() uut.Deserialize(ref reader); } - [TestMethod] - public void Equals_Null() - { - var uut = new Header(); - Assert.IsFalse(uut.Equals(null)); - } - [TestMethod] public void CloneTest() { @@ -108,7 +102,7 @@ public void CloneTest() [TestMethod] public void Equals_SameHeader() { - var uut = new Header(); + var uut = (Header)RuntimeHelpers.GetUninitializedObject(typeof(Header)); Assert.IsTrue(uut.Equals(uut)); } @@ -125,7 +119,7 @@ public void Equals_SameHash() [TestMethod] public void Equals_SameObject() { - var uut = new Header(); + var uut = (Header)RuntimeHelpers.GetUninitializedObject(typeof(Header)); Assert.IsTrue(uut.Equals((object)uut)); } @@ -139,7 +133,7 @@ public void Serialize() [TestMethod] public void TestWitness() { - IVerifiable item = new Header(); + IVerifiable item = (Header)RuntimeHelpers.GetUninitializedObject(typeof(Header)); void Actual() => item.Witnesses = null; Assert.ThrowsExactly(Actual); diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_HighPriorityAttribute.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_HighPriorityAttribute.cs index a8b96996c8..d3c3bda484 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_HighPriorityAttribute.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_HighPriorityAttribute.cs @@ -76,9 +76,9 @@ public void Verify() var test = new HighPriorityAttribute(); var snapshotCache = TestBlockchain.GetTestSnapshotCache(); - Assert.IsFalse(test.Verify(snapshotCache, new Transaction() { Signers = Array.Empty() })); - Assert.IsFalse(test.Verify(snapshotCache, new Transaction() { Signers = new Signer[] { new Signer() { Account = UInt160.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff01") } } })); - Assert.IsTrue(test.Verify(snapshotCache, new Transaction() { Signers = new Signer[] { new Signer() { Account = NativeContract.NEO.GetCommitteeAddress(snapshotCache) } } })); + Assert.IsFalse(test.Verify(snapshotCache, new Transaction() { Signers = Array.Empty(), Attributes = [test], Witnesses = null! })); + Assert.IsFalse(test.Verify(snapshotCache, new Transaction() { Signers = new Signer[] { new Signer() { Account = UInt160.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff01") } }, Attributes = [test], Witnesses = null! })); + Assert.IsTrue(test.Verify(snapshotCache, new Transaction() { Signers = new Signer[] { new Signer() { Account = NativeContract.NEO.GetCommitteeAddress(snapshotCache) } }, Attributes = [test], Witnesses = null! })); } } } diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_NotValidBefore.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_NotValidBefore.cs index 458b2078ea..b96c42742f 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_NotValidBefore.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_NotValidBefore.cs @@ -80,9 +80,9 @@ public void Verify() var snapshotCache = TestBlockchain.GetTestSnapshotCache(); test.Height = NativeContract.Ledger.CurrentIndex(snapshotCache) + 1; - Assert.IsFalse(test.Verify(snapshotCache, new Transaction())); + Assert.IsFalse(test.Verify(snapshotCache, new Transaction { Signers = null!, Attributes = [test], Witnesses = null! })); test.Height--; - Assert.IsTrue(test.Verify(snapshotCache, new Transaction())); + Assert.IsTrue(test.Verify(snapshotCache, new Transaction { Signers = null!, Attributes = [test], Witnesses = null! })); } } } diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_NotaryAssisted.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_NotaryAssisted.cs index b4e66146dd..5dfd9864a4 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_NotaryAssisted.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_NotaryAssisted.cs @@ -66,9 +66,9 @@ public void Verify() var attr = new NotaryAssisted() { NKeys = 4 }; // Temporary use Notary contract hash stub for valid transaction. - var txGood = new Transaction { Signers = [new() { Account = s_notaryHash }, new() { Account = UInt160.Zero }] }; - var txBad1 = new Transaction { Signers = [new() { Account = s_notaryHash }] }; - var txBad2 = new Transaction { Signers = [new() { Account = UInt160.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff01") }] }; + var txGood = new Transaction { Signers = [new() { Account = s_notaryHash }, new() { Account = UInt160.Zero }], Attributes = [attr], Witnesses = null! }; + var txBad1 = new Transaction { Signers = [new() { Account = s_notaryHash }], Attributes = [attr], Witnesses = null! }; + var txBad2 = new Transaction { Signers = [new() { Account = UInt160.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff01") }], Attributes = [attr], Witnesses = null! }; var snapshot = TestBlockchain.GetTestSnapshotCache(); Assert.IsTrue(attr.Verify(snapshot, txGood)); @@ -81,7 +81,7 @@ public void CalculateNetworkFee() { var snapshot = TestBlockchain.GetTestSnapshotCache(); var attr = new NotaryAssisted() { NKeys = 4 }; - var tx = new Transaction { Signers = [new() { Account = s_notaryHash }] }; + var tx = new Transaction { Signers = [new() { Account = s_notaryHash }], Attributes = [attr], Witnesses = null! }; Assert.AreEqual((4 + 1) * 1000_0000, attr.CalculateNetworkFee(snapshot, tx)); } diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs index cdcd4a8f24..538ebdeeef 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs @@ -10,7 +10,6 @@ // modifications are permitted. using Microsoft.VisualStudio.TestTools.UnitTesting; -using Neo.Cryptography.ECC; using Neo.Extensions; using Neo.IO; using Neo.Json; @@ -25,6 +24,7 @@ using System.Collections.Generic; using System.Linq; using System.Numerics; +using System.Runtime.CompilerServices; using Array = System.Array; namespace Neo.UnitTests.Network.P2P.Payloads @@ -37,7 +37,7 @@ public class UT_Transaction [TestInitialize] public void TestSetup() { - _uut = new Transaction(); + _uut = (Transaction)RuntimeHelpers.GetUninitializedObject(typeof(Transaction)); } [TestMethod] @@ -110,22 +110,23 @@ public void Size_Get() public void CheckNoItems() { var snapshotCache = TestBlockchain.GetTestSnapshotCache(); + byte[] script = [(byte)OpCode.PUSH0, (byte)OpCode.DROP]; var tx = new Transaction { NetworkFee = 1000000, SystemFee = 1000000, Script = ReadOnlyMemory.Empty, + Signers = [new() { Account = script.ToScriptHash() }], Attributes = [], Witnesses = [ new() { InvocationScript = ReadOnlyMemory.Empty, - VerificationScript = new byte[]{ (byte)OpCode.PUSH0, (byte)OpCode.DROP } + VerificationScript = script } ] }; - tx.Signers = [new() { Account = tx.Witnesses[0].ScriptHash }]; Assert.IsFalse(tx.VerifyWitnesses(TestProtocolSettings.Default, snapshotCache, tx.NetworkFee)); } @@ -237,7 +238,6 @@ public void FeeIsSignatureContractDetailed() ], acc.ScriptHash); Assert.IsNotNull(tx); - Assert.IsNull(tx.Witnesses); // check pre-computed network fee (already guessing signature sizes) Assert.AreEqual(1228520L, tx.NetworkFee); @@ -352,7 +352,6 @@ public void FeeIsSignatureContract_TestScope_Global() var tx = wallet.MakeTransaction(snapshotCache, script, acc.ScriptHash, signers); Assert.IsNotNull(tx); - Assert.IsNull(tx.Witnesses); // ---- // Sign @@ -433,7 +432,6 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_GAS() var tx = wallet.MakeTransaction(snapshotCache, script, acc.ScriptHash, signers); Assert.IsNotNull(tx); - Assert.IsNull(tx.Witnesses); // ---- // Sign @@ -518,7 +516,6 @@ public void FeeIsSignatureContract_TestScope_CalledByEntry_Plus_GAS() var tx = wallet.MakeTransaction(snapshotCache, script, acc.ScriptHash, signers); Assert.IsNotNull(tx); - Assert.IsNull(tx.Witnesses); // ---- // Sign @@ -645,7 +642,6 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_GAS() var tx = wallet.MakeTransaction(snapshotCache, script, acc.ScriptHash, signers); Assert.IsNotNull(tx); - Assert.IsNull(tx.Witnesses); // ---- // Sign @@ -990,8 +986,8 @@ public void Transaction_Serialize_Deserialize_MaxSizeSigners() [TestMethod] public void FeeIsSignatureContract_TestScope_FeeOnly_Default() { - // Global is supposed to be default - var signer = new Signer(); + // None is supposed to be default + var signer = (Signer)RuntimeHelpers.GetUninitializedObject(typeof(Signer)); Assert.AreEqual(WitnessScope.None, signer.Scopes); var wallet = TestUtils.GenerateTestWallet(""); @@ -1036,7 +1032,6 @@ public void FeeIsSignatureContract_TestScope_FeeOnly_Default() var tx = wallet.MakeTransaction(snapshotCache, script, acc.ScriptHash, signers); Assert.IsNotNull(tx); - Assert.IsNull(tx.Witnesses); // ---- // Sign @@ -1302,11 +1297,11 @@ public void Test_VerifyStateInDependent_Multi() "IDIpqGSDpKiWUd4BgwhAqeDS+mzLimB0VfLW706y0LP0R6lw7ECJNekTpjFkQ8bDCECuixw9ZlvNXpDGYcFhZ+uLP6hPhFyligA" + "dys9WIqdSr0XQZ7Q3Do="); - var tx = new Transaction(); + var tx = (Transaction)RuntimeHelpers.GetUninitializedObject(typeof(Transaction)); MemoryReader reader = new(txData); ((ISerializable)tx).Deserialize(ref reader); - var settings = new ProtocolSettings() { Network = 844378958 }; + var settings = ProtocolSettings.Default with { Network = 844378958 }; var result = tx.VerifyStateIndependent(settings); Assert.AreEqual(VerifyResult.Succeed, result); } diff --git a/tests/Neo.UnitTests/Network/P2P/UT_TaskManagerMailbox.cs b/tests/Neo.UnitTests/Network/P2P/UT_TaskManagerMailbox.cs index 6f269f28cb..15eee79778 100644 --- a/tests/Neo.UnitTests/Network/P2P/UT_TaskManagerMailbox.cs +++ b/tests/Neo.UnitTests/Network/P2P/UT_TaskManagerMailbox.cs @@ -44,17 +44,17 @@ public void TestSetup() public void TaskManager_Test_IsHighPriority() { // high priority - Assert.IsTrue(uut.IsHighPriority(new TaskManager.Register())); - Assert.IsTrue(uut.IsHighPriority(new TaskManager.RestartTasks())); + Assert.IsTrue(uut.IsHighPriority(new TaskManager.Register(null!))); + Assert.IsTrue(uut.IsHighPriority(new TaskManager.RestartTasks(null!))); // low priority // -> NewTasks: generic InvPayload - Assert.IsFalse(uut.IsHighPriority(new TaskManager.NewTasks { Payload = new InvPayload() })); + Assert.IsFalse(uut.IsHighPriority(new TaskManager.NewTasks(new InvPayload { Hashes = null! }))); // high priority // -> NewTasks: payload Block or Consensus - Assert.IsTrue(uut.IsHighPriority(new TaskManager.NewTasks { Payload = new InvPayload { Type = InventoryType.Block } })); - Assert.IsTrue(uut.IsHighPriority(new TaskManager.NewTasks { Payload = new InvPayload { Type = InventoryType.Extensible } })); + Assert.IsTrue(uut.IsHighPriority(new TaskManager.NewTasks(new InvPayload { Type = InventoryType.Block, Hashes = null! }))); + Assert.IsTrue(uut.IsHighPriority(new TaskManager.NewTasks(new InvPayload { Type = InventoryType.Extensible, Hashes = null! }))); // any random object should not have priority object obj = null; diff --git a/tests/Neo.UnitTests/Network/P2P/UT_TaskSession.cs b/tests/Neo.UnitTests/Network/P2P/UT_TaskSession.cs index 1cd4e15ff3..dacd4e925a 100644 --- a/tests/Neo.UnitTests/Network/P2P/UT_TaskSession.cs +++ b/tests/Neo.UnitTests/Network/P2P/UT_TaskSession.cs @@ -23,14 +23,14 @@ public class UT_TaskSession [TestMethod] public void CreateTest() { - var ses = new TaskSession(new VersionPayload() { Capabilities = new NodeCapability[] { new FullNodeCapability(123) } }); + var ses = new TaskSession(new VersionPayload() { Capabilities = new NodeCapability[] { new FullNodeCapability(123) }, UserAgent = "" }); Assert.IsFalse(ses.HasTooManyTasks); Assert.AreEqual((uint)123, ses.LastBlockIndex); Assert.IsEmpty(ses.IndexTasks); Assert.IsTrue(ses.IsFullNode); - ses = new TaskSession(new VersionPayload() { Capabilities = Array.Empty() }); + ses = new TaskSession(new VersionPayload() { Capabilities = Array.Empty(), UserAgent = "" }); Assert.IsFalse(ses.HasTooManyTasks); Assert.AreEqual((uint)0, ses.LastBlockIndex); diff --git a/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractGroup.cs b/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractGroup.cs index 8048acb3c8..61e7dbe379 100644 --- a/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractGroup.cs +++ b/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractGroup.cs @@ -15,6 +15,7 @@ using Neo.SmartContract; using Neo.SmartContract.Manifest; using Neo.Wallets; +using System.Runtime.CompilerServices; namespace Neo.UnitTests.SmartContract.Manifest { @@ -32,7 +33,7 @@ public void TestClone() Signature = new byte[20] }; - ContractGroup clone = new(); + ContractGroup clone = (ContractGroup)RuntimeHelpers.GetUninitializedObject(typeof(ContractGroup)); ((IInteroperable)clone).FromStackItem(contractGroup.ToStackItem(null)); Assert.AreEqual(clone.ToJson().ToString(), contractGroup.ToJson().ToString()); } diff --git a/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs b/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs index 4482d891be..1fed43f8b5 100644 --- a/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs +++ b/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs @@ -20,6 +20,7 @@ using System; using System.IO; using System.Linq; +using System.Runtime.CompilerServices; using System.Text.RegularExpressions; using Array = Neo.VM.Types.Array; @@ -361,14 +362,14 @@ public void TestDeserializeAndSerialize() var expected = TestUtils.CreateDefaultManifest(); expected.Extra = (JObject)JToken.Parse(@"{""a"":123}"); - var clone = new ContractManifest(); + var clone = (ContractManifest)RuntimeHelpers.GetUninitializedObject(typeof(ContractManifest)); ((IInteroperable)clone).FromStackItem(expected.ToStackItem(null)); Assert.AreEqual(@"{""a"":123}", expected.Extra.ToString()); Assert.AreEqual(expected.ToString(), clone.ToString()); expected.Extra = null; - clone = new ContractManifest(); + clone = (ContractManifest)RuntimeHelpers.GetUninitializedObject(typeof(ContractManifest)); ((IInteroperable)clone).FromStackItem(expected.ToStackItem(null)); Assert.AreEqual(expected.Extra, clone.Extra); @@ -391,12 +392,5 @@ public void TestSerializeTrusts() // Wildcard trust should be represented as Null stackitem (not as zero-length ByteString): Assert.AreEqual(((Array)actualTrusts)[1], StackItem.Null); } - - [TestMethod] - public void TestGenerator() - { - ContractManifest contractManifest = new(); - Assert.IsNotNull(contractManifest); - } } } diff --git a/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractPermission.cs b/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractPermission.cs index 5bfe52afdc..547e1b7d61 100644 --- a/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractPermission.cs +++ b/tests/Neo.UnitTests/SmartContract/Manifest/UT_ContractPermission.cs @@ -54,22 +54,22 @@ public void TestIsAllowed() ContractManifest contractManifest1 = TestUtils.CreateDefaultManifest(); ContractPermission contractPermission1 = ContractPermission.DefaultPermission; contractPermission1.Contract = ContractPermissionDescriptor.Create(UInt160.Zero); - Assert.IsTrue(contractPermission1.IsAllowed(new() { Hash = UInt160.Zero, Manifest = contractManifest1 }, "AAA")); + Assert.IsTrue(contractPermission1.IsAllowed(new() { Hash = UInt160.Zero, Nef = null!, Manifest = contractManifest1 }, "AAA")); contractPermission1.Contract = ContractPermissionDescriptor.CreateWildcard(); ContractManifest contractManifest2 = TestUtils.CreateDefaultManifest(); ContractPermission contractPermission2 = ContractPermission.DefaultPermission; contractPermission2.Contract = ContractPermissionDescriptor.Create(UInt160.Parse("0x0000000000000000000000000000000000000001")); - Assert.IsFalse(contractPermission2.IsAllowed(new() { Hash = UInt160.Zero, Manifest = contractManifest2 }, "AAA")); + Assert.IsFalse(contractPermission2.IsAllowed(new() { Hash = UInt160.Zero, Nef = null!, Manifest = contractManifest2 }, "AAA")); contractPermission2.Contract = ContractPermissionDescriptor.CreateWildcard(); byte[] privateKey3 = RandomNumberFactory.NextBytes(32); ECPoint publicKey3 = ECCurve.Secp256r1.G * privateKey3; ContractManifest contractManifest3 = TestUtils.CreateDefaultManifest(); - contractManifest3.Groups = [new ContractGroup() { PubKey = publicKey3 }]; + contractManifest3.Groups = [new ContractGroup() { PubKey = publicKey3, Signature = null! }]; ContractPermission contractPermission3 = ContractPermission.DefaultPermission; contractPermission3.Contract = ContractPermissionDescriptor.Create(publicKey3); - Assert.IsTrue(contractPermission3.IsAllowed(new() { Hash = UInt160.Zero, Manifest = contractManifest3 }, "AAA")); + Assert.IsTrue(contractPermission3.IsAllowed(new() { Hash = UInt160.Zero, Nef = null!, Manifest = contractManifest3 }, "AAA")); contractPermission3.Contract = ContractPermissionDescriptor.CreateWildcard(); byte[] privateKey41 = RandomNumberFactory.NextBytes(32); @@ -77,10 +77,10 @@ public void TestIsAllowed() byte[] privateKey42 = RandomNumberFactory.NextBytes(32); ECPoint publicKey42 = ECCurve.Secp256r1.G * privateKey42; ContractManifest contractManifest4 = TestUtils.CreateDefaultManifest(); - contractManifest4.Groups = [new ContractGroup() { PubKey = publicKey42 }]; + contractManifest4.Groups = [new ContractGroup() { PubKey = publicKey42, Signature = null! }]; ContractPermission contractPermission4 = ContractPermission.DefaultPermission; contractPermission4.Contract = ContractPermissionDescriptor.Create(publicKey41); - Assert.IsFalse(contractPermission4.IsAllowed(new() { Hash = UInt160.Zero, Manifest = contractManifest4 }, "AAA")); + Assert.IsFalse(contractPermission4.IsAllowed(new() { Hash = UInt160.Zero, Nef = null!, Manifest = contractManifest4 }, "AAA")); contractPermission4.Contract = ContractPermissionDescriptor.CreateWildcard(); } } diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_GasToken.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_GasToken.cs index d395022d37..dbe33dd4d8 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_GasToken.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_GasToken.cs @@ -10,19 +10,17 @@ // modifications are permitted. using Microsoft.VisualStudio.TestTools.UnitTesting; -using Neo.Cryptography.ECC; using Neo.Extensions; using Neo.Network.P2P.Payloads; using Neo.Persistence; using Neo.SmartContract; using Neo.SmartContract.Native; using Neo.UnitTests.Extensions; -using Neo.VM; -using Neo.Wallets; using System; using System.Collections.Generic; using System.Linq; using System.Numerics; +using System.Runtime.CompilerServices; using System.Threading.Tasks; namespace Neo.UnitTests.SmartContract.Native @@ -37,7 +35,7 @@ public class UT_GasToken public void TestSetup() { _snapshotCache = TestBlockchain.GetTestSnapshotCache(); - _persistingBlock = new Block { Header = new Header() }; + _persistingBlock = (Block)RuntimeHelpers.GetUninitializedObject(typeof(Block)); } [TestMethod] @@ -53,7 +51,18 @@ public void TestSetup() public async Task Check_BalanceOfTransferAndBurn() { var snapshot = _snapshotCache.CloneCache(); - var persistingBlock = new Block { Header = new Header { Index = 1000 } }; + var persistingBlock = new Block + { + Header = new Header + { + PrevHash = UInt256.Zero, + MerkleRoot = UInt256.Zero, + Index = 1000, + NextConsensus = UInt160.Zero, + Witness = null! + }, + Transactions = [] + }; byte[] from = Contract.GetBFTAddress(TestProtocolSettings.Default.StandbyValidators).ToArray(); byte[] to = new byte[20]; var supply = NativeContract.GAS.TotalSupply(snapshot); diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs index 9297af0951..03f58a8dbd 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_NativeContract.cs @@ -22,6 +22,7 @@ using System.IO; using System.Linq; using System.Reflection; +using System.Runtime.CompilerServices; namespace Neo.UnitTests.SmartContract.Native { @@ -270,7 +271,7 @@ internal static ContractState Call_GetContract(DataCache snapshot, UInt160 addre var result = engine.ResultStack.Pop(); Assert.IsInstanceOfType(result, typeof(VM.Types.Array)); - var cs = new ContractState(); + var cs = (ContractState)RuntimeHelpers.GetUninitializedObject(typeof(ContractState)); ((IInteroperable)cs).FromStackItem(result); return cs; diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_NeoToken.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_NeoToken.cs index 19943efd96..5174f9a4ab 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_NeoToken.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_NeoToken.cs @@ -24,6 +24,7 @@ using System.IO; using System.Linq; using System.Numerics; +using System.Runtime.CompilerServices; using System.Text; using static Neo.SmartContract.Native.NeoToken; using Array = System.Array; @@ -43,7 +44,7 @@ public void TestSetup() _snapshotCache = TestBlockchain.GetTestSnapshotCache(); _persistingBlock = new Block { - Header = new Header(), + Header = (Header)RuntimeHelpers.GetUninitializedObject(typeof(Header)), Transactions = Array.Empty() }; } @@ -65,7 +66,11 @@ public void Test_HF_EchidnaStates() var settings = ProtocolSettings.Load(stream); var clonedCache = _snapshotCache.CloneCache(); - var persistingBlock = new Block { Header = new Header() }; + var persistingBlock = new Block + { + Header = (Header)RuntimeHelpers.GetUninitializedObject(typeof(Header)), + Transactions = [] + }; foreach (var method in new string[] { "vote", "registerCandidate", "unregisterCandidate" }) { @@ -103,7 +108,18 @@ public void Test_HF_EchidnaStates() public void Check_Vote() { var clonedCache = _snapshotCache.CloneCache(); - var persistingBlock = new Block { Header = new Header { Index = 1000 } }; + var persistingBlock = new Block + { + Header = new Header + { + PrevHash = UInt256.Zero, + MerkleRoot = UInt256.Zero, + Index = 1000, + NextConsensus = UInt160.Zero, + Witness = null! + }, + Transactions = [] + }; var storageKey = new KeyBuilder(NativeContract.Ledger.Id, 12); clonedCache.Add(storageKey, new StorageItem(new HashIndexState { Hash = UInt256.Zero, Index = persistingBlock.Index - 1 })); @@ -161,7 +177,18 @@ public void Check_Vote() public void Check_Vote_Sameaccounts() { var clonedCache = _snapshotCache.CloneCache(); - var persistingBlock = new Block { Header = new Header { Index = 1000 } }; + var persistingBlock = new Block + { + Header = new Header + { + PrevHash = UInt256.Zero, + MerkleRoot = UInt256.Zero, + Index = 1000, + NextConsensus = UInt160.Zero, + Witness = null! + }, + Transactions = [] + }; var storageKey = new KeyBuilder(NativeContract.Ledger.Id, 12); clonedCache.Add(storageKey, new StorageItem(new HashIndexState { Hash = UInt256.Zero, Index = persistingBlock.Index - 1 })); @@ -194,7 +221,18 @@ public void Check_Vote_Sameaccounts() public void Check_Vote_ChangeVote() { var clonedCache = _snapshotCache.CloneCache(); - var persistingBlock = new Block { Header = new Header { Index = 1000 } }; + var persistingBlock = new Block + { + Header = new Header + { + PrevHash = UInt256.Zero, + MerkleRoot = UInt256.Zero, + Index = 1000, + NextConsensus = UInt160.Zero, + Witness = null! + }, + Transactions = [] + }; var storageKey = new KeyBuilder(NativeContract.Ledger.Id, 12); clonedCache.Add(storageKey, new StorageItem(new HashIndexState { Hash = UInt256.Zero, Index = persistingBlock.Index - 1 })); //from vote to G @@ -229,7 +267,18 @@ public void Check_Vote_ChangeVote() public void Check_Vote_VoteToNull() { var clonedCache = _snapshotCache.CloneCache(); - var persistingBlock = new Block { Header = new Header { Index = 1000 } }; + var persistingBlock = new Block + { + Header = new Header + { + PrevHash = UInt256.Zero, + MerkleRoot = UInt256.Zero, + Index = 1000, + NextConsensus = UInt160.Zero, + Witness = null! + }, + Transactions = [] + }; var storageKey = new KeyBuilder(NativeContract.Ledger.Id, 12); clonedCache.Add(storageKey, new StorageItem(new HashIndexState { Hash = UInt256.Zero, Index = persistingBlock.Index - 1 })); byte[] from = TestProtocolSettings.Default.StandbyValidators[0].ToArray(); @@ -266,7 +315,18 @@ public void Check_Vote_VoteToNull() public void Check_UnclaimedGas() { var clonedCache = _snapshotCache.CloneCache(); - var persistingBlock = new Block { Header = new Header { Index = 1000 } }; + var persistingBlock = new Block + { + Header = new Header + { + PrevHash = UInt256.Zero, + MerkleRoot = UInt256.Zero, + Index = 1000, + NextConsensus = UInt160.Zero, + Witness = null! + }, + Transactions = [] + }; var storageKey = new KeyBuilder(NativeContract.Ledger.Id, 12); clonedCache.Add(storageKey, new StorageItem(new HashIndexState { Hash = UInt256.Zero, Index = persistingBlock.Index - 1 })); @@ -472,7 +532,18 @@ public void Check_GetCommittee() public void Check_Transfer() { var clonedCache = _snapshotCache.CloneCache(); - var persistingBlock = new Block { Header = new Header { Index = 1000 } }; + var persistingBlock = new Block + { + Header = new Header + { + PrevHash = UInt256.Zero, + MerkleRoot = UInt256.Zero, + Index = 1000, + NextConsensus = UInt160.Zero, + Witness = null! + }, + Transactions = [] + }; byte[] from = Contract.GetBFTAddress(TestProtocolSettings.Default.StandbyValidators).ToArray(); byte[] to = new byte[20]; @@ -578,7 +649,7 @@ public void Check_Initialize() public void TestCalculateBonus() { var clonedCache = _snapshotCache.CloneCache(); - var persistingBlock = new Block(); + var persistingBlock = (Block)RuntimeHelpers.GetUninitializedObject(typeof(Block)); StorageKey key = CreateStorageKey(20, UInt160.Zero.ToArray()); @@ -835,13 +906,28 @@ public void TestEconomicParameter() { const byte Prefix_CurrentBlock = 12; var clonedCache = _snapshotCache.CloneCache(); - var persistingBlock = new Block { Header = new Header() }; + var persistingBlock = new Block + { + Header = (Header)RuntimeHelpers.GetUninitializedObject(typeof(Header)), + Transactions = [] + }; (BigInteger, bool) result = Check_GetGasPerBlock(clonedCache, persistingBlock); Assert.IsTrue(result.Item2); Assert.AreEqual(5 * NativeContract.GAS.Factor, result.Item1); - persistingBlock = new Block { Header = new Header { Index = 10 } }; + persistingBlock = new Block + { + Header = new Header + { + PrevHash = UInt256.Zero, + MerkleRoot = UInt256.Zero, + Index = 10, + NextConsensus = UInt160.Zero, + Witness = null! + }, + Transactions = [] + }; (Boolean, bool) result1 = Check_SetGasPerBlock(clonedCache, 10 * NativeContract.GAS.Factor, persistingBlock); Assert.IsTrue(result1.Item2); Assert.IsTrue(result1.Item1.GetBoolean()); diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_Notary.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_Notary.cs index 3eb59cc7ef..1101c603b9 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_Notary.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_Notary.cs @@ -26,6 +26,7 @@ using System.Linq; using System.Numerics; using System.Reflection; +using System.Runtime.CompilerServices; namespace Neo.UnitTests.SmartContract.Native { @@ -39,7 +40,7 @@ public class UT_Notary public void TestSetup() { _snapshot = TestBlockchain.GetTestSnapshotCache(); - _persistingBlock = new Block { Header = new() }; + _persistingBlock = (Block)RuntimeHelpers.GetUninitializedObject(typeof(Block)); } [TestMethod] @@ -52,7 +53,18 @@ public void Check_Name() public void Check_OnNEP17Payment() { var snapshot = _snapshot.CloneCache(); - var persistingBlock = new Block { Header = new Header { Index = 1000 } }; + var persistingBlock = new Block + { + Header = new Header + { + PrevHash = UInt256.Zero, + MerkleRoot = UInt256.Zero, + Index = 1000, + NextConsensus = UInt160.Zero, + Witness = null! + }, + Transactions = [] + }; var from = Contract.GetBFTAddress(TestProtocolSettings.Default.StandbyValidators).ToArray(); var to = NativeContract.Notary.Hash.ToArray(); @@ -117,7 +129,18 @@ public void Check_OnNEP17Payment() public void Check_ExpirationOf() { var snapshot = _snapshot.CloneCache(); - var persistingBlock = new Block { Header = new Header { Index = 1000 } }; + var persistingBlock = new Block + { + Header = new Header + { + PrevHash = UInt256.Zero, + MerkleRoot = UInt256.Zero, + Index = 1000, + NextConsensus = UInt160.Zero, + Witness = null! + }, + Transactions = [] + }; var from = Contract.GetBFTAddress(TestProtocolSettings.Default.StandbyValidators).ToArray(); var ntr = NativeContract.Notary.Hash.ToArray(); @@ -189,7 +212,18 @@ public void Check_ExpirationOf() public void Check_LockDepositUntil() { var snapshot = _snapshot.CloneCache(); - var persistingBlock = new Block { Header = new Header { Index = 1000 } }; + var persistingBlock = new Block + { + Header = new Header + { + PrevHash = UInt256.Zero, + MerkleRoot = UInt256.Zero, + Index = 1000, + NextConsensus = UInt160.Zero, + Witness = null! + }, + Transactions = [] + }; var from = Contract.GetBFTAddress(TestProtocolSettings.Default.StandbyValidators).ToArray(); // Set proper current index for deposit's Till parameter check. @@ -239,7 +273,18 @@ public void Check_LockDepositUntil() public void Check_BalanceOf() { var snapshot = _snapshot.CloneCache(); - var persistingBlock = new Block { Header = new Header { Index = 1000 } }; + var persistingBlock = new Block + { + Header = new Header + { + PrevHash = UInt256.Zero, + MerkleRoot = UInt256.Zero, + Index = 1000, + NextConsensus = UInt160.Zero, + Witness = null! + }, + Transactions = [] + }; var fromAddr = Contract.GetBFTAddress(TestProtocolSettings.Default.StandbyValidators); var from = fromAddr.ToArray(); var hash = NativeContract.Notary.Hash.ToArray(); @@ -324,7 +369,11 @@ public void Check_BalanceOf() var ret = NativeContract.RoleManagement.Call( snapshot, new Nep17NativeContractExtensions.ManualWitness(committeeMultiSigAddr), - new Block { Header = new() }, + new Block + { + Header = (Header)RuntimeHelpers.GetUninitializedObject(typeof(Header)), + Transactions = [] + }, "designateAsRole", new ContractParameter(ContractParameterType.Integer) { Value = new BigInteger((int)Role.P2PNotary) }, new ContractParameter(ContractParameterType.Array) @@ -362,7 +411,18 @@ public void Check_BalanceOf() public void Check_Withdraw() { var snapshot = _snapshot.CloneCache(); - var persistingBlock = new Block { Header = new Header { Index = 1000 } }; + var persistingBlock = new Block + { + Header = new Header + { + PrevHash = UInt256.Zero, + MerkleRoot = UInt256.Zero, + Index = 1000, + NextConsensus = UInt160.Zero, + Witness = null! + }, + Transactions = [] + }; var fromAddr = Contract.GetBFTAddress(TestProtocolSettings.Default.StandbyValidators); var from = fromAddr.ToArray(); @@ -450,6 +510,7 @@ internal static bool Call_LockDepositUntil(DataCache snapshot, byte[] address, u { Signers = [new() { Account = new UInt160(address), Scopes = WitnessScope.Global }], Attributes = [], + Witnesses = null! }, snapshot, persistingBlock, settings: TestProtocolSettings.Default); @@ -477,6 +538,7 @@ internal static bool Call_Withdraw(DataCache snapshot, byte[] from, byte[] to, B { Signers = [new() { Account = accFrom, Scopes = WitnessScope.Global }], Attributes = [], + Witnesses = null! }, snapshot, persistingBlock, settings: TestProtocolSettings.Default); @@ -506,7 +568,18 @@ public void Check_GetMaxNotValidBeforeDelta() public void Check_SetMaxNotValidBeforeDelta() { var snapshot = _snapshot.CloneCache(); - var persistingBlock = new Block { Header = new Header { Index = 1000 } }; + var persistingBlock = new Block + { + Header = new Header + { + PrevHash = UInt256.Zero, + MerkleRoot = UInt256.Zero, + Index = 1000, + NextConsensus = UInt160.Zero, + Witness = null! + }, + Transactions = [] + }; var committeeAddress = NativeContract.NEO.GetCommitteeAddress(snapshot); using var engine = ApplicationEngine.Create(TriggerType.Application, @@ -566,7 +639,11 @@ public void Check_OnPersist_FeePerKeyUpdate() var ret = NativeContract.RoleManagement.Call( snapshot, new Nep17NativeContractExtensions.ManualWitness(committeeMultiSigAddr), - new Block { Header = new() }, + new Block + { + Header = (Header)RuntimeHelpers.GetUninitializedObject(typeof(Header)), + Transactions = [] + }, "designateAsRole", new ContractParameter(ContractParameterType.Integer) { Value = new BigInteger((int)Role.P2PNotary) }, new ContractParameter(ContractParameterType.Array) @@ -689,7 +766,11 @@ public void Check_OnPersist_NotaryRewards() var ret = NativeContract.RoleManagement.Call( snapshot, new Nep17NativeContractExtensions.ManualWitness(committeeMultiSigAddr), - new Block { Header = new() }, + new Block + { + Header = (Header)RuntimeHelpers.GetUninitializedObject(typeof(Header)), + Transactions = [] + }, "designateAsRole", new ContractParameter(ContractParameterType.Integer) { Value = new BigInteger((int)Role.P2PNotary) }, new ContractParameter(ContractParameterType.Array) diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs index 6a7c37cda8..07dd41df5c 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs @@ -63,9 +63,13 @@ public void Check_SetAttributeFee() { Header = new Header { + PrevHash = UInt256.Zero, + MerkleRoot = UInt256.Zero, Index = 1000, - PrevHash = UInt256.Zero - } + NextConsensus = UInt160.Zero, + Witness = null! + }, + Transactions = [] }; var attr = new ContractParameter(ContractParameterType.Integer) { Value = (BigInteger)(byte)TransactionAttributeType.Conflicts }; @@ -123,9 +127,13 @@ public void Check_SetFeePerByte() { Header = new Header { + PrevHash = UInt256.Zero, + MerkleRoot = UInt256.Zero, Index = 1000, - PrevHash = UInt256.Zero - } + NextConsensus = UInt160.Zero, + Witness = null! + }, + Transactions = [] }; // Without signature @@ -162,9 +170,13 @@ public void Check_SetBaseExecFee() { Header = new Header { + PrevHash = UInt256.Zero, + MerkleRoot = UInt256.Zero, Index = 1000, - PrevHash = UInt256.Zero - } + NextConsensus = UInt160.Zero, + Witness = null! + }, + Transactions = [] }; // Without signature @@ -212,9 +224,13 @@ public void Check_SetStoragePrice() { Header = new Header { + PrevHash = UInt256.Zero, + MerkleRoot = UInt256.Zero, Index = 1000, - PrevHash = UInt256.Zero - } + NextConsensus = UInt160.Zero, + Witness = null! + }, + Transactions = [] }; // Without signature @@ -261,9 +277,13 @@ public void Check_SetMaxValidUntilBlockIncrement() { Header = new Header { + PrevHash = UInt256.Zero, + MerkleRoot = UInt256.Zero, Index = 1000, - PrevHash = UInt256.Zero - } + NextConsensus = UInt160.Zero, + Witness = null! + }, + Transactions = [] }; // Without signature @@ -321,9 +341,13 @@ public void Check_SetMillisecondsPerBlock() { Header = new Header { + PrevHash = UInt256.Zero, + MerkleRoot = UInt256.Zero, Index = 1000, - PrevHash = UInt256.Zero - } + NextConsensus = UInt160.Zero, + Witness = null! + }, + Transactions = [] }; // Without signature. @@ -379,9 +403,13 @@ public void Check_BlockAccount() { Header = new Header { + PrevHash = UInt256.Zero, + MerkleRoot = UInt256.Zero, Index = 1000, - PrevHash = UInt256.Zero - } + NextConsensus = UInt160.Zero, + Witness = null! + }, + Transactions = [] }; // Without signature @@ -435,9 +463,13 @@ public void Check_Block_UnblockAccount() { Header = new Header { + PrevHash = UInt256.Zero, + MerkleRoot = UInt256.Zero, Index = 1000, - PrevHash = UInt256.Zero - } + NextConsensus = UInt160.Zero, + Witness = null! + }, + Transactions = [] }; UInt160 committeeMultiSigAddr = NativeContract.NEO.GetCommitteeAddress(snapshot); @@ -490,9 +522,13 @@ public void Check_SetMaxTraceableBlocks() { Header = new Header { + PrevHash = UInt256.Zero, + MerkleRoot = UInt256.Zero, Index = 1000, - PrevHash = UInt256.Zero - } + NextConsensus = UInt160.Zero, + Witness = null! + }, + Transactions = [] }; // Without signature. @@ -562,9 +598,13 @@ public void TestListBlockedAccounts() { Header = new Header { + PrevHash = UInt256.Zero, + MerkleRoot = UInt256.Zero, Index = 1000, - PrevHash = UInt256.Zero - } + NextConsensus = UInt160.Zero, + Witness = null! + }, + Transactions = [] }; UInt160 committeeMultiSigAddr = NativeContract.NEO.GetCommitteeAddress(snapshot); diff --git a/tests/Neo.UnitTests/SmartContract/Native/UT_RoleManagement.cs b/tests/Neo.UnitTests/SmartContract/Native/UT_RoleManagement.cs index c457269efd..fc36640181 100644 --- a/tests/Neo.UnitTests/SmartContract/Native/UT_RoleManagement.cs +++ b/tests/Neo.UnitTests/SmartContract/Native/UT_RoleManagement.cs @@ -12,7 +12,6 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Extensions; using Neo.Network.P2P.Payloads; -using Neo.Persistence; using Neo.SmartContract; using Neo.SmartContract.Native; using Neo.UnitTests.Extensions; @@ -21,6 +20,7 @@ using System.Collections.Generic; using System.Linq; using System.Numerics; +using System.Runtime.CompilerServices; using System.Security.Cryptography; using Array = Neo.VM.Types.Array; using ECPoint = Neo.Cryptography.ECC.ECPoint; @@ -66,7 +66,11 @@ public void TestSetAndGet() var ret = NativeContract.RoleManagement.Call( snapshot1, new Nep17NativeContractExtensions.ManualWitness(committeeMultiSigAddr), - new Block { Header = new Header() }, + new Block + { + Header = (Header)RuntimeHelpers.GetUninitializedObject(typeof(Header)), + Transactions = [] + }, "designateAsRole", Ev, new ContractParameter(ContractParameterType.Integer) { Value = new BigInteger((int)role) }, new ContractParameter(ContractParameterType.Array) { Value = publicKeys.Select(p => new ContractParameter(ContractParameterType.ByteArray) { Value = p.ToArray() }).ToList() } diff --git a/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.Runtime.cs b/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.Runtime.cs index 7c619ff564..354915c7ec 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.Runtime.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.Runtime.cs @@ -41,10 +41,16 @@ public void TestNotSupportedNotification() engine.LoadScript(Array.Empty()); engine.CurrentContext.GetState().Contract = new() { + Hash = UInt160.Zero, + Nef = null!, Manifest = new() { + Name = "", + Groups = [], + SupportedStandards = [], Abi = new() { + Methods = [], Events = new[] { new ContractEventDescriptor @@ -54,12 +60,15 @@ public void TestNotSupportedNotification() { new ContractParameterDefinition { + Name = "p1", Type = ContractParameterType.Array } } } } - } + }, + Permissions = [], + Trusts = WildcardContainer.CreateWildcard() } }; diff --git a/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.cs b/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.cs index c41ed86ec9..29bb46e740 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.cs @@ -145,16 +145,26 @@ public void TestSystem_Contract_Call_Permissions() engine.LoadScript(script.ToArray()); engine.CurrentContext.GetState().Contract = new() { + Hash = UInt160.Zero, + Nef = null!, Manifest = new() { - Abi = new(), + Name = "", + Groups = [], + SupportedStandards = [], + Abi = new() + { + Methods = [], + Events = [] + }, Permissions = [ new ContractPermission { Contract = ContractPermissionDescriptor.Create(scriptHash), Methods = WildcardContainer.Create(["test"]) // allowed to call only "test" method of the target contract. } - ] + ], + Trusts = WildcardContainer.CreateWildcard() } }; var currentScriptHash = engine.EntryScriptHash; @@ -181,16 +191,26 @@ public void TestSystem_Contract_Call_Permissions() engine.LoadScript(script.ToArray()); engine.CurrentContext.GetState().Contract = new() { + Hash = UInt160.Zero, + Nef = null!, Manifest = new() { - Abi = new(), + Name = "", + Groups = [], + SupportedStandards = [], + Abi = new() + { + Methods = [], + Events = [] + }, Permissions = [ new ContractPermission { Contract = ContractPermissionDescriptor.Create(scriptHash), Methods = WildcardContainer.Create(["test"]) // allowed to call only "test" method of the target contract. } - ] + ], + Trusts = WildcardContainer.CreateWildcard() } }; var currentScriptHash = engine.EntryScriptHash; diff --git a/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngineProvider.cs b/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngineProvider.cs index 717783e106..f26a038583 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngineProvider.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngineProvider.cs @@ -60,7 +60,18 @@ public void TestDefaultAppEngineProvider() [TestMethod] public void TestInitNonce() { - var block = new Block { Header = new() { Nonce = 0x0102030405060708 } }; + var block = new Block + { + Header = new() + { + PrevHash = UInt256.Zero, + MerkleRoot = UInt256.Zero, + Nonce = 0x0102030405060708, + NextConsensus = UInt160.Zero, + Witness = null! + }, + Transactions = [] + }; using var app = new TestEngine(TriggerType.Application, null, null, block, TestProtocolSettings.Default, 0, null, null); diff --git a/tests/Neo.UnitTests/SmartContract/UT_Contract.cs b/tests/Neo.UnitTests/SmartContract/UT_Contract.cs index 7556f59151..f1297413ea 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_Contract.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_Contract.cs @@ -178,7 +178,7 @@ public void TestSignatureRedeemScriptFee() var fee = PolicyContract.DefaultExecFeeFactor * (ApplicationEngine.OpCodePriceTable[(byte)OpCode.PUSHDATA1] * 2 + ApplicationEngine.OpCodePriceTable[(byte)OpCode.SYSCALL] + ApplicationEngine.CheckSigPrice); using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, - new Transaction { Signers = Array.Empty(), Attributes = Array.Empty() }, snapshot, settings: TestProtocolSettings.Default)) + new Transaction { Signers = Array.Empty(), Attributes = Array.Empty(), Witnesses = [] }, snapshot, settings: TestProtocolSettings.Default)) { engine.LoadScript(invocation.Concat(verification).ToArray(), configureState: p => p.CallFlags = CallFlags.None); engine.Execute(); @@ -208,7 +208,7 @@ public void TestCreateMultiSigRedeemScriptFee() long fee = PolicyContract.DefaultExecFeeFactor * (ApplicationEngine.OpCodePriceTable[(byte)OpCode.PUSHDATA1] * (2 + 2) + ApplicationEngine.OpCodePriceTable[(byte)OpCode.PUSHINT8] * 2 + ApplicationEngine.OpCodePriceTable[(byte)OpCode.SYSCALL] + ApplicationEngine.CheckSigPrice * 2); using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, - new Transaction { Signers = Array.Empty(), Attributes = Array.Empty() }, snapshot, settings: TestProtocolSettings.Default)) + new Transaction { Signers = Array.Empty(), Attributes = Array.Empty(), Witnesses = [] }, snapshot, settings: TestProtocolSettings.Default)) { engine.LoadScript(invocation.Concat(verification).ToArray(), configureState: p => p.CallFlags = CallFlags.None); engine.Execute(); diff --git a/tests/Neo.UnitTests/SmartContract/UT_ContractParameterContext.cs b/tests/Neo.UnitTests/SmartContract/UT_ContractParameterContext.cs index bbeb3f298a..72799d1ca0 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_ContractParameterContext.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_ContractParameterContext.cs @@ -19,6 +19,7 @@ using Neo.Wallets; using System; using System.Linq; +using System.Runtime.CompilerServices; using System.Text.RegularExpressions; namespace Neo.UnitTests.SmartContract @@ -164,12 +165,19 @@ public void TestAddSignature() var context = new ContractParametersContext(snapshotCache, tx, TestProtocolSettings.Default.Network); Assert.IsTrue(context.AddSignature(contract, key.PublicKey, [0x01])); - var contract1 = Contract.CreateSignatureContract(key.PublicKey); - contract1.ParameterList = Array.Empty(); + var contract1 = new Contract + { + Script = Contract.CreateSignatureRedeemScript(key.PublicKey), + ParameterList = Array.Empty() + }; context = new ContractParametersContext(snapshotCache, tx, TestProtocolSettings.Default.Network); Assert.IsFalse(context.AddSignature(contract1, key.PublicKey, [0x01])); - contract1.ParameterList = [ContractParameterType.Signature, ContractParameterType.Signature]; + contract1 = new Contract + { + Script = Contract.CreateSignatureRedeemScript(key.PublicKey), + ParameterList = [ContractParameterType.Signature, ContractParameterType.Signature] + }; Action action1 = () => context.AddSignature(contract1, key.PublicKey, [0x01]); Assert.ThrowsExactly(action1); @@ -207,13 +215,15 @@ public void TestAddWithScriptHash() var contract = new ContractState() { Hash = h160, - Nef = new(), + Nef = (NefFile)RuntimeHelpers.GetUninitializedObject(typeof(NefFile)), Manifest = new() { Name = "TestContract", Groups = [], SupportedStandards = [], - Abi = new() { Methods = [new() { Name = ContractBasicMethod.Verify, Parameters = [] }], Events = [] } + Abi = new() { Methods = [new() { Name = ContractBasicMethod.Verify, Parameters = [] }], Events = [] }, + Permissions = [], + Trusts = WildcardContainer.CreateWildcard() } }; snapshotCache.AddContract(h160, contract); diff --git a/tests/Neo.UnitTests/SmartContract/UT_ContractState.cs b/tests/Neo.UnitTests/SmartContract/UT_ContractState.cs index c0948ca2ac..0e14594c44 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_ContractState.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_ContractState.cs @@ -15,6 +15,7 @@ using Neo.SmartContract.Manifest; using Neo.VM; using System; +using System.Runtime.CompilerServices; namespace Neo.UnitTests.SmartContract { @@ -75,7 +76,7 @@ public void TestClone() [TestMethod] public void TestIInteroperable() { - IInteroperable newContract = new ContractState(); + IInteroperable newContract = (ContractState)RuntimeHelpers.GetUninitializedObject(typeof(ContractState)); newContract.FromStackItem(contract.ToStackItem(null)); Assert.AreEqual(contract.Manifest.ToJson().ToString(), ((ContractState)newContract).Manifest.ToJson().ToString()); Assert.IsTrue(((ContractState)newContract).Script.Span.SequenceEqual(contract.Script.Span)); @@ -84,8 +85,8 @@ public void TestIInteroperable() [TestMethod] public void TestCanCall() { - var temp = new ContractState() { Manifest = TestUtils.CreateDefaultManifest() }; - Assert.IsTrue(temp.CanCall(new() { Hash = UInt160.Zero, Manifest = TestUtils.CreateDefaultManifest() }, "AAA")); + var temp = new ContractState() { Hash = UInt160.Zero, Nef = null!, Manifest = TestUtils.CreateDefaultManifest() }; + Assert.IsTrue(temp.CanCall(new() { Hash = UInt160.Zero, Nef = null!, Manifest = TestUtils.CreateDefaultManifest() }, "AAA")); } [TestMethod] diff --git a/tests/Neo.UnitTests/SmartContract/UT_DeployedContract.cs b/tests/Neo.UnitTests/SmartContract/UT_DeployedContract.cs index d6e65c1659..3e285b672d 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_DeployedContract.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_DeployedContract.cs @@ -26,19 +26,31 @@ public void TestGetScriptHash() { Manifest = new ContractManifest() { + Name = "", + Groups = [], + SupportedStandards = [], Abi = new ContractAbi() { Methods = new ContractMethodDescriptor[] - { - new ContractMethodDescriptor() - { - Name = "verify", - Parameters = Array.Empty() - } - } - } + { + new ContractMethodDescriptor() + { + Name = "verify", + Parameters = Array.Empty() + } + }, + Events = [] + }, + Permissions = [], + Trusts = WildcardContainer.CreateWildcard() + }, + Nef = new NefFile + { + Compiler = "", + Source = "", + Tokens = [], + Script = new byte[] { 1, 2, 3 } }, - Nef = new NefFile { Script = new byte[] { 1, 2, 3 } }, Hash = new byte[] { 1, 2, 3 }.ToScriptHash() }); @@ -51,21 +63,34 @@ public void TestErrors() Assert.ThrowsExactly(() => _ = new DeployedContract(null)); Assert.ThrowsExactly(() => _ = new DeployedContract(new ContractState() { + Hash = UInt160.Zero, Manifest = new ContractManifest() { + Name = "", + Groups = [], + SupportedStandards = [], Abi = new ContractAbi() { Methods = new ContractMethodDescriptor[] - { - new ContractMethodDescriptor() - { - Name = "noverify", - Parameters = Array.Empty() - } - } - } + { + new ContractMethodDescriptor() + { + Name = "noverify", + Parameters = Array.Empty() + } + }, + Events = [] + }, + Permissions = [], + Trusts = WildcardContainer.CreateWildcard() }, - Nef = new NefFile { Script = new byte[] { 1, 2, 3 } } + Nef = new NefFile + { + Compiler = "", + Source = "", + Tokens = [], + Script = new byte[] { 1, 2, 3 } + } })); } } diff --git a/tests/Neo.UnitTests/SmartContract/UT_InteropService.cs b/tests/Neo.UnitTests/SmartContract/UT_InteropService.cs index 8c78b6296f..ce2914566b 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_InteropService.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_InteropService.cs @@ -26,6 +26,7 @@ using Neo.Wallets; using System; using System.Linq; +using System.Runtime.CompilerServices; using System.Security.Cryptography; using System.Text; using Array = System.Array; @@ -144,10 +145,16 @@ public void Runtime_GetNotifications_Test() engine.LoadScript(script.ToArray()); engine.CurrentContext.GetState().Contract = new() { + Hash = UInt160.Zero, + Nef = null!, Manifest = new() { + Name = "", + Groups = [], + SupportedStandards = [], Abi = new() { + Methods = [], Events = [ new ContractEventDescriptor @@ -164,7 +171,8 @@ public void Runtime_GetNotifications_Test() Contract = ContractPermissionDescriptor.Create(scriptHash2), Methods = WildcardContainer.Create(["test"]) } - ] + ], + Trusts = WildcardContainer.CreateWildcard() } }; var currentScriptHash = engine.EntryScriptHash; @@ -221,10 +229,16 @@ public void Runtime_GetNotifications_Test() engine.LoadScript(script.ToArray()); engine.CurrentContext.GetState().Contract = new() { + Hash = UInt160.Zero, + Nef = null!, Manifest = new() { + Name = "", + Groups = [], + SupportedStandards = [], Abi = new() { + Methods = [], Events = [ new ContractEventDescriptor @@ -241,7 +255,8 @@ public void Runtime_GetNotifications_Test() Contract = ContractPermissionDescriptor.Create(scriptHash2), Methods = WildcardContainer.Create(["test"]) } - ] + ], + Trusts = WildcardContainer.CreateWildcard() } }; var currentScriptHash = engine.EntryScriptHash; @@ -377,7 +392,11 @@ public void TestRuntime_Log() [TestMethod] public void TestRuntime_GetTime() { - Block block = new() { Header = new Header() }; + Block block = new() + { + Header = (Header)RuntimeHelpers.GetUninitializedObject(typeof(Header)), + Transactions = [] + }; var engine = GetEngine(true, hasBlock: true); Assert.AreEqual(block.Timestamp, engine.GetTime()); } @@ -783,7 +802,11 @@ private ApplicationEngine GetEngine(bool hasContainer = false, bool hasBlock = f { var snapshot = _snapshotCache.CloneCache(); var tx = hasContainer ? TestUtils.GetTransaction(UInt160.Zero) : null; - var block = hasBlock ? new Block { Header = new Header() } : null; + var block = hasBlock ? new Block + { + Header = (Header)RuntimeHelpers.GetUninitializedObject(typeof(Header)), + Transactions = [] + } : null; var engine = ApplicationEngine.Create(TriggerType.Application, tx, snapshot, block, TestProtocolSettings.Default, gas: gas); if (addScript) engine.LoadScript(new byte[] { 0x01 }); return engine; diff --git a/tests/Neo.UnitTests/SmartContract/UT_LogEventArgs.cs b/tests/Neo.UnitTests/SmartContract/UT_LogEventArgs.cs index 8d7a9e1c1a..5d0e60ae07 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_LogEventArgs.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_LogEventArgs.cs @@ -12,6 +12,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Network.P2P.Payloads; using Neo.SmartContract; +using System.Runtime.CompilerServices; namespace Neo.UnitTests.SmartContract { @@ -21,7 +22,7 @@ public class UT_LogEventArgs [TestMethod] public void TestGeneratorAndGet() { - IVerifiable container = new Header(); + IVerifiable container = (Header)RuntimeHelpers.GetUninitializedObject(typeof(Header)); UInt160 scripthash = UInt160.Zero; string message = "lalala"; LogEventArgs logEventArgs = new LogEventArgs(container, scripthash, message); diff --git a/tests/Neo.UnitTests/SmartContract/UT_NefFile.cs b/tests/Neo.UnitTests/SmartContract/UT_NefFile.cs index a843d523dd..2d50e05a6b 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_NefFile.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_NefFile.cs @@ -15,6 +15,7 @@ using Neo.SmartContract; using System; using System.IO; +using System.Runtime.CompilerServices; namespace Neo.UnitTests.SmartContract { @@ -45,7 +46,7 @@ public void TestDeserialize() ((ISerializable)file).Serialize(writer); ms.Seek(0, SeekOrigin.Begin); ms.Write(wrongMagic, 0, 4); - ISerializable newFile = new NefFile(); + ISerializable newFile = (NefFile)RuntimeHelpers.GetUninitializedObject(typeof(NefFile)); Assert.ThrowsExactly(() => { MemoryReader reader = new(ms.ToArray()); @@ -59,7 +60,7 @@ public void TestDeserialize() using (BinaryWriter writer = new(ms)) { ((ISerializable)file).Serialize(writer); - ISerializable newFile = new NefFile(); + ISerializable newFile = (NefFile)RuntimeHelpers.GetUninitializedObject(typeof(NefFile)); Assert.ThrowsExactly(() => { MemoryReader reader = new(ms.ToArray()); @@ -74,7 +75,7 @@ public void TestDeserialize() using (BinaryWriter writer = new(ms)) { ((ISerializable)file).Serialize(writer); - ISerializable newFile = new NefFile(); + ISerializable newFile = (NefFile)RuntimeHelpers.GetUninitializedObject(typeof(NefFile)); Assert.ThrowsExactly(() => { MemoryReader reader = new(ms.ToArray()); diff --git a/tests/Neo.UnitTests/SmartContract/UT_SmartContractHelper.cs b/tests/Neo.UnitTests/SmartContract/UT_SmartContractHelper.cs index 80141e522d..8a1b4c6705 100644 --- a/tests/Neo.UnitTests/SmartContract/UT_SmartContractHelper.cs +++ b/tests/Neo.UnitTests/SmartContract/UT_SmartContractHelper.cs @@ -18,6 +18,7 @@ using Neo.Wallets; using System; using System.Linq; +using System.Runtime.CompilerServices; using System.Security.Cryptography; using ECPoint = Neo.Cryptography.ECC.ECPoint; using Helper = Neo.SmartContract.Helper; @@ -139,7 +140,13 @@ public void TestVerifyWitnesses() Hashes = [UInt256.Zero], }); TestUtils.BlocksDelete(snapshotCache1, index1); - Assert.IsFalse(Helper.VerifyWitnesses(new Header() { PrevHash = index1 }, TestProtocolSettings.Default, snapshotCache1, 100)); + Assert.IsFalse(Helper.VerifyWitnesses(new Header() + { + PrevHash = index1, + MerkleRoot = UInt256.Zero, + NextConsensus = UInt160.Zero, + Witness = null! + }, TestProtocolSettings.Default, snapshotCache1, 100)); var snapshotCache2 = TestBlockchain.GetTestSnapshotCache(); var index2 = UInt256.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff01"); @@ -156,9 +163,15 @@ public void TestVerifyWitnesses() Hashes = [UInt256.Zero], }; TestUtils.BlocksAdd(snapshotCache2, index2, block2); - Header header2 = new() { PrevHash = index2, Witness = Witness.Empty }; + Header header2 = new() + { + PrevHash = index2, + MerkleRoot = UInt256.Zero, + NextConsensus = UInt160.Zero, + Witness = Witness.Empty + }; - snapshotCache2.AddContract(UInt160.Zero, new ContractState()); + snapshotCache2.AddContract(UInt160.Zero, (ContractState)RuntimeHelpers.GetUninitializedObject(typeof(ContractState))); snapshotCache2.DeleteContract(UInt160.Zero); Assert.IsFalse(Helper.VerifyWitnesses(header2, TestProtocolSettings.Default, snapshotCache2, 100)); @@ -186,7 +199,7 @@ public void TestVerifyWitnesses() }; snapshotCache3.AddContract(UInt160.Zero, new ContractState() { - Nef = new NefFile { Script = ReadOnlyMemory.Empty }, + Nef = (NefFile)RuntimeHelpers.GetUninitializedObject(typeof(NefFile)), Hash = Array.Empty().ToScriptHash(), Manifest = TestUtils.CreateManifest("verify", ContractParameterType.Boolean, ContractParameterType.Signature), }); @@ -196,7 +209,13 @@ public void TestVerifyWitnesses() var contract = new ContractState() { - Nef = new NefFile { Script = "11".HexToBytes() }, // 17 PUSH1 + Nef = new NefFile + { + Compiler = "", + Source = "", + Tokens = [], + Script = "11".HexToBytes() + }, // 17 PUSH1 Hash = "11".HexToBytes().ToScriptHash(), Manifest = TestUtils.CreateManifest("verify", ContractParameterType.Boolean, ContractParameterType.Signature), // Offset = 0 }; diff --git a/tests/Neo.UnitTests/TestUtils.Block.cs b/tests/Neo.UnitTests/TestUtils.Block.cs index 14807cf782..00afc6c747 100644 --- a/tests/Neo.UnitTests/TestUtils.Block.cs +++ b/tests/Neo.UnitTests/TestUtils.Block.cs @@ -22,6 +22,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; namespace Neo.UnitTests { @@ -57,7 +58,7 @@ public static Header MakeHeader(DataCache snapshot, UInt256 prevHash) public static Block MakeBlock(DataCache snapshot, UInt256 prevHash, int numberOfTransactions) { - var block = new Block(); + var block = (Block)RuntimeHelpers.GetUninitializedObject(typeof(Block)); var header = MakeHeader(snapshot, prevHash); var transactions = new Transaction[numberOfTransactions]; if (numberOfTransactions > 0) @@ -89,7 +90,7 @@ public static Block CreateBlockWithValidTransactions(DataCache snapshot, public static Block CreateBlockWithValidTransactions(DataCache snapshot, WalletAccount account, Transaction[] transactions) { - var block = new Block(); + var block = (Block)RuntimeHelpers.GetUninitializedObject(typeof(Block)); var key = NativeContract.Ledger.CreateStorageKey(Prefix_CurrentBlock); var state = snapshot.TryGet(key).GetInteroperable(); var header = MakeHeader(snapshot, state.Hash); diff --git a/tests/Neo.UnitTests/TestUtils.Transaction.cs b/tests/Neo.UnitTests/TestUtils.Transaction.cs index 4c2c92bf5c..d69d8a5cf9 100644 --- a/tests/Neo.UnitTests/TestUtils.Transaction.cs +++ b/tests/Neo.UnitTests/TestUtils.Transaction.cs @@ -168,7 +168,8 @@ public static Transaction CreateInvalidTransaction(DataCache snapshot, NEP6Walle ValidUntilBlock = NativeContract.Ledger.CurrentIndex(snapshot) + wallet.ProtocolSettings.MaxValidUntilBlockIncrement, Signers = [new Signer { Account = sender, Scopes = WitnessScope.CalledByEntry }], Attributes = [], - Script = new[] { (byte)OpCode.RET } + Script = new[] { (byte)OpCode.RET }, + Witnesses = [] }; switch (type) diff --git a/tests/Neo.UnitTests/TestWalletAccount.cs b/tests/Neo.UnitTests/TestWalletAccount.cs index 0216c55221..b9714aa249 100644 --- a/tests/Neo.UnitTests/TestWalletAccount.cs +++ b/tests/Neo.UnitTests/TestWalletAccount.cs @@ -26,10 +26,12 @@ class TestWalletAccount : WalletAccount public TestWalletAccount(UInt160 hash) : base(hash, TestProtocolSettings.Default) { - var mock = new Mock(); + var mock = new Mock(() => new Contract + { + Script = Contract.CreateSignatureRedeemScript(key.PublicKey), + ParameterList = new[] { ContractParameterType.Signature } + }); mock.SetupGet(p => p.ScriptHash).Returns(hash); - mock.Object.Script = Contract.CreateSignatureRedeemScript(key.PublicKey); - mock.Object.ParameterList = new[] { ContractParameterType.Signature }; Contract = mock.Object; } diff --git a/tests/Neo.UnitTests/UT_Helper.cs b/tests/Neo.UnitTests/UT_Helper.cs index 90d506d1ee..9944a4233f 100644 --- a/tests/Neo.UnitTests/UT_Helper.cs +++ b/tests/Neo.UnitTests/UT_Helper.cs @@ -21,6 +21,7 @@ using System.Linq; using System.Net; using System.Numerics; +using System.Runtime.CompilerServices; namespace Neo.UnitTests { @@ -38,7 +39,7 @@ public void GetSignData() [TestMethod] public void TestTryGetHash() { - var tx = new Transaction(); + var tx = (Transaction)RuntimeHelpers.GetUninitializedObject(typeof(Transaction)); Assert.IsFalse(tx.TryGetHash(out _)); } diff --git a/tests/Neo.UnitTests/Wallets/NEP6/UT_NEP6Wallet.cs b/tests/Neo.UnitTests/Wallets/NEP6/UT_NEP6Wallet.cs index 4d181435b7..7b880ece3b 100644 --- a/tests/Neo.UnitTests/Wallets/NEP6/UT_NEP6Wallet.cs +++ b/tests/Neo.UnitTests/Wallets/NEP6/UT_NEP6Wallet.cs @@ -90,6 +90,7 @@ public void TestCreateAccount() Attributes = [], Script = new byte[1], Signers = [new Signer() { Account = acc.ScriptHash }], + Witnesses = [] }; var ctx = new ContractParametersContext(TestBlockchain.GetTestSnapshotCache(), tx, TestProtocolSettings.Default.Network); Assert.IsTrue(uut.Sign(ctx));