Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[Neo Core] Nullable #3125

Closed
wants to merge 38 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
96437ea
nullable and use nullable network
Jim8y Feb 8, 2024
57383c9
add helper methods
Jim8y Feb 8, 2024
9f16138
fix UT
Jim8y Feb 8, 2024
8145c4d
use nullable crypto
Jim8y Feb 8, 2024
f687908
use nullable smartcontract
Jim8y Feb 8, 2024
28a1cca
Revert "use nullable smartcontract"
Jim8y Feb 8, 2024
d91a92c
Revert "use nullable crypto"
Jim8y Feb 8, 2024
3db49dc
Revert "Revert "use nullable crypto""
Jim8y Feb 8, 2024
119cc80
use nullable ledger
Jim8y Feb 8, 2024
0143dd1
update UInt 160 and 256
Jim8y Feb 8, 2024
23511bc
use nullable wallet
Jim8y Feb 8, 2024
53f8196
revoke wallet
Jim8y Feb 8, 2024
fecb839
nullable IO
Jim8y Feb 8, 2024
6240fca
use part of contract nullable
Jim8y Feb 8, 2024
343cb9b
Revert "use part of contract nullable"
Jim8y Feb 8, 2024
9960d06
nullable manifest
Jim8y Feb 8, 2024
921010c
Merge branch 'master' into nullable
Jim8y Feb 9, 2024
b38b617
nullable contract
Jim8y Feb 9, 2024
a12e8b1
smart contract nullable
Jim8y Feb 9, 2024
e4c6c18
add more nullable to contracts
Jim8y Feb 9, 2024
ba7b50d
more contract nullable
Jim8y Feb 9, 2024
103ad43
Merge branch 'nullable' of github.com:Jim8y/neo into nullable
Jim8y Feb 9, 2024
af3fc79
more nullable for smart contract
Jim8y Feb 9, 2024
cfaa143
fix UT
Jim8y Feb 9, 2024
666983a
more nullable to smart contract
Jim8y Feb 9, 2024
52c01de
more nullable to smart contract
Jim8y Feb 9, 2024
6e86102
update format
Jim8y Feb 9, 2024
0337a17
more nullable, 570 nullable warnings to go
Jim8y Feb 9, 2024
8d7558b
add more nullable
Jim8y Feb 9, 2024
e1470a2
fix more nullable for smart contract
Jim8y Feb 9, 2024
81e125e
add more nullable
Jim8y Feb 9, 2024
113d90d
null wallet
Jim8y Feb 9, 2024
ac031b8
nullable Iapplicationengineprovider
Jim8y Feb 9, 2024
44c4528
nullable applicationengine
Jim8y Feb 9, 2024
2925445
Revert "nullable applicationengine"
Jim8y Feb 9, 2024
cebbec3
fix more nullable, 370 warning to go
Jim8y Feb 9, 2024
e975e21
290 warning to go.
Jim8y Feb 9, 2024
a75b502
format
Jim8y Feb 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/Neo/Cryptography/Crypto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ public static bool VerifySignature(ReadOnlySpan<byte> message, ReadOnlySpan<byte
var curve = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp256k1");
var domain = new Org.BouncyCastle.Crypto.Parameters.ECDomainParameters(curve.Curve, curve.G, curve.N, curve.H);
var point = curve.Curve.CreatePoint(
new Org.BouncyCastle.Math.BigInteger(pubkey.X.Value.ToString()),
new Org.BouncyCastle.Math.BigInteger(pubkey.Y.Value.ToString()));
new Org.BouncyCastle.Math.BigInteger(pubkey.X!.Value.ToString()),
new Org.BouncyCastle.Math.BigInteger(pubkey.Y!.Value.ToString()));
var pubKey = new Org.BouncyCastle.Crypto.Parameters.ECPublicKeyParameters("ECDSA", point, domain);
var signer = new Org.BouncyCastle.Crypto.Signers.ECDsaSigner();
signer.Init(false, pubKey);
Expand Down
12 changes: 6 additions & 6 deletions src/Neo/Cryptography/ECC/ECFieldElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ public ECFieldElement(BigInteger value, ECCurve curve)
this.curve = curve;
}

public int CompareTo(ECFieldElement other)
public int CompareTo(ECFieldElement? other)
{
if (ReferenceEquals(this, other)) return 0;
if (!curve.Equals(other.curve)) throw new InvalidOperationException("Invalid comparision for points with different curves");
if (!curve.Equals(other?.curve)) throw new InvalidOperationException("Invalid comparision for points with different curves");
return Value.CompareTo(other.Value);
}

public override bool Equals(object obj)
public override bool Equals(object? obj)
{
if (obj == this)
return true;
Expand All @@ -47,9 +47,9 @@ public override bool Equals(object obj)
return Equals(other);
}

public bool Equals(ECFieldElement other)
public bool Equals(ECFieldElement? other)
{
return Value.Equals(other.Value) && curve.Equals(other.curve);
return Value.Equals(other?.Value) && curve.Equals(other.curve);
}

private static BigInteger[] FastLucasSequence(BigInteger p, BigInteger P, BigInteger Q, BigInteger k)
Expand Down Expand Up @@ -104,7 +104,7 @@ public override int GetHashCode()
return Value.GetHashCode();
}

public ECFieldElement Sqrt()
public ECFieldElement? Sqrt()
{
if (curve.Q.TestBit(1))
{
Expand Down
58 changes: 29 additions & 29 deletions src/Neo/Cryptography/ECC/ECPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ namespace Neo.Cryptography.ECC
/// </summary>
public class ECPoint : IComparable<ECPoint>, IEquatable<ECPoint>, ISerializable
{
internal ECFieldElement X, Y;
internal ECFieldElement? X, Y;
internal readonly ECCurve Curve;
private byte[] _compressedPoint, _uncompressedPoint;
private byte[]? _compressedPoint, _uncompressedPoint;

/// <summary>
/// Indicates whether it is a point at infinity.
Expand All @@ -37,15 +37,15 @@ public bool IsInfinity

public int Size => IsInfinity ? 1 : 33;

private static IO.Caching.ECPointCache pointCacheK1 { get; } = new(1000);
private static IO.Caching.ECPointCache pointCacheR1 { get; } = new(1000);
private static ECPointCache pointCacheK1 { get; } = new(1000);
private static ECPointCache pointCacheR1 { get; } = new(1000);

/// <summary>
/// Initializes a new instance of the <see cref="ECPoint"/> class with the secp256r1 curve.
/// </summary>
public ECPoint() : this(null, null, ECCurve.Secp256r1) { }

internal ECPoint(ECFieldElement x, ECFieldElement y, ECCurve curve)
internal ECPoint(ECFieldElement? x, ECFieldElement? y, ECCurve curve)
{
if ((x is null ^ y is null) || (curve is null))
throw new ArgumentException("Exactly one of the field elements is null");
Expand All @@ -54,13 +54,13 @@ internal ECPoint(ECFieldElement x, ECFieldElement y, ECCurve curve)
this.Curve = curve;
}

public int CompareTo(ECPoint other)
public int CompareTo(ECPoint? other)
{
if (!Curve.Equals(other.Curve)) throw new InvalidOperationException("Invalid comparision for points with different curves");
if (!Curve.Equals(other?.Curve)) throw new InvalidOperationException("Invalid comparision for points with different curves");
if (ReferenceEquals(this, other)) return 0;
int result = X.CompareTo(other.X);
int result = X!.CompareTo(other.X);
if (result != 0) return result;
return Y.CompareTo(other.Y);
return Y!.CompareTo(other.Y);
}

/// <summary>
Expand All @@ -71,7 +71,7 @@ public int CompareTo(ECPoint other)
/// <returns>The decoded point.</returns>
public static ECPoint DecodePoint(ReadOnlySpan<byte> encoded, ECCurve curve)
{
ECPoint p = null;
ECPoint? p = null;
switch (encoded[0])
{
case 0x02: // compressed
Expand Down Expand Up @@ -102,7 +102,7 @@ public static ECPoint DecodePoint(ReadOnlySpan<byte> encoded, ECCurve curve)

private static ECPoint DecompressPoint(ReadOnlySpan<byte> encoded, ECCurve curve)
{
ECPointCache pointCache = null;
ECPointCache? pointCache;
if (curve == ECCurve.Secp256k1) pointCache = pointCacheK1;
else if (curve == ECCurve.Secp256r1) pointCache = pointCacheR1;
else throw new FormatException("Invalid curve " + curve);
Expand All @@ -123,7 +123,7 @@ private static ECPoint DecompressPoint(int yTilde, BigInteger X1, ECCurve curve)
{
ECFieldElement x = new(X1, curve);
ECFieldElement alpha = x * (x.Square() + curve.A) + curve.B;
ECFieldElement beta = alpha.Sqrt();
ECFieldElement? beta = alpha.Sqrt();

//
// if we can't find a sqrt we haven't got a point on the
Expand Down Expand Up @@ -187,27 +187,27 @@ public byte[] EncodePoint(bool commpressed)
{
if (_uncompressedPoint != null) return _uncompressedPoint;
data = new byte[65];
byte[] yBytes = Y.Value.ToByteArray(isUnsigned: true, isBigEndian: true);
byte[] yBytes = Y!.Value.ToByteArray(isUnsigned: true, isBigEndian: true);
Buffer.BlockCopy(yBytes, 0, data, 65 - yBytes.Length, yBytes.Length);
}
byte[] xBytes = X.Value.ToByteArray(isUnsigned: true, isBigEndian: true);
byte[] xBytes = X!.Value.ToByteArray(isUnsigned: true, isBigEndian: true);
Buffer.BlockCopy(xBytes, 0, data, 33 - xBytes.Length, xBytes.Length);
data[0] = commpressed ? Y.Value.IsEven ? (byte)0x02 : (byte)0x03 : (byte)0x04;
data[0] = commpressed ? Y!.Value.IsEven ? (byte)0x02 : (byte)0x03 : (byte)0x04;
if (commpressed) _compressedPoint = data;
else _uncompressedPoint = data;
return data;
}

public bool Equals(ECPoint other)
public bool Equals(ECPoint? other)
{
if (ReferenceEquals(this, other)) return true;
if (other is null) return false;
if (IsInfinity && other.IsInfinity) return true;
if (IsInfinity || other.IsInfinity) return false;
return X.Equals(other.X) && Y.Equals(other.Y);
return X!.Equals(other.X) && Y!.Equals(other.Y);
}

public override bool Equals(object obj)
public override bool Equals(object? obj)
{
return Equals(obj as ECPoint);
}
Expand All @@ -231,7 +231,7 @@ public static ECPoint FromBytes(byte[] bytes, ECCurve curve)

public override int GetHashCode()
{
return X.GetHashCode() + Y.GetHashCode();
return X!.GetHashCode() + Y!.GetHashCode();
}

internal static ECPoint Multiply(ECPoint p, BigInteger k)
Expand Down Expand Up @@ -361,7 +361,7 @@ public override string ToString()
/// <param name="curve">The <see cref="ECCurve"/> object used to construct the <see cref="ECPoint"/>.</param>
/// <param name="point">The parsed point.</param>
/// <returns><see langword="true"/> if <paramref name="value"/> was converted successfully; otherwise, <see langword="false"/>.</returns>
public static bool TryParse(string value, ECCurve curve, out ECPoint point)
public static bool TryParse(string value, ECCurve curve, out ECPoint? point)
{
try
{
Expand All @@ -379,13 +379,13 @@ internal ECPoint Twice()
{
if (this.IsInfinity)
return this;
if (this.Y.Value.Sign == 0)
if (this.Y?.Value.Sign == 0)
return Curve.Infinity;
ECFieldElement TWO = new(2, Curve);
ECFieldElement THREE = new(3, Curve);
ECFieldElement gamma = (this.X.Square() * THREE + Curve.A) / (Y * TWO);
ECFieldElement gamma = (this.X!.Square() * THREE + Curve.A) / (Y! * TWO);
ECFieldElement x3 = gamma.Square() - this.X * TWO;
ECFieldElement y3 = gamma * (this.X - x3) - this.Y;
ECFieldElement y3 = gamma * (this.X - x3) - this.Y!;
return new ECPoint(x3, y3, Curve);
}

Expand Down Expand Up @@ -426,7 +426,7 @@ private static sbyte[] WindowNaf(sbyte width, BigInteger k)

public static ECPoint operator -(ECPoint x)
{
return new ECPoint(x.X, -x.Y, x.Curve);
return new ECPoint(x.X, -x.Y!, x.Curve);
}

public static ECPoint operator *(ECPoint p, byte[] n)
Expand All @@ -449,15 +449,15 @@ private static sbyte[] WindowNaf(sbyte width, BigInteger k)
return y;
if (y.IsInfinity)
return x;
if (x.X.Equals(y.X))
if (x.X!.Equals(y.X))
{
if (x.Y.Equals(y.Y))
if (x.Y!.Equals(y.Y))
return x.Twice();
return x.Curve.Infinity;
}
ECFieldElement gamma = (y.Y - x.Y) / (y.X - x.X);
ECFieldElement x3 = gamma.Square() - x.X - y.X;
ECFieldElement y3 = gamma * (x.X - x3) - x.Y;
ECFieldElement gamma = (y.Y! - x.Y!) / (y.X! - x.X);
ECFieldElement x3 = gamma.Square() - x.X - y.X!;
ECFieldElement y3 = gamma * (x.X - x3) - x.Y!;
return new ECPoint(x3, y3, x.Curve);
}

Expand Down
4 changes: 2 additions & 2 deletions src/Neo/Cryptography/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ public static byte[] Sha256(this Span<byte> value)
return Sha256((ReadOnlySpan<byte>)value);
}

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 != 12) throw new ArgumentOutOfRangeException(nameof(nonce));
var tag = new byte[16];
Expand All @@ -179,7 +179,7 @@ public static byte[] AES256Encrypt(this byte[] plainData, byte[] key, byte[] non
return Concat(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)
{
ReadOnlySpan<byte> encrypted = encryptedData;
var nonce = encrypted[..12];
Expand Down
14 changes: 7 additions & 7 deletions src/Neo/Cryptography/MerkleTree.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace Neo.Cryptography
/// </summary>
public class MerkleTree
{
private readonly MerkleTreeNode root;
private readonly MerkleTreeNode? root;

/// <summary>
/// The depth of the tree.
Expand All @@ -40,7 +40,7 @@ internal MerkleTree(UInt256[] hashes)
this.Depth = depth;
}

private static MerkleTreeNode Build(MerkleTreeNode[] leaves)
private static MerkleTreeNode? Build(MerkleTreeNode[] leaves)
{
if (leaves.Length == 0) return null;
if (leaves.Length == 1) return leaves[0];
Expand All @@ -63,7 +63,7 @@ private static MerkleTreeNode Build(MerkleTreeNode[] leaves)
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
}
Expand All @@ -87,7 +87,7 @@ public static UInt256 ComputeRoot(UInt256[] hashes)
if (hashes.Length == 0) return UInt256.Zero;
if (hashes.Length == 1) return hashes[0];
MerkleTree tree = new(hashes);
return tree.root.Hash;
return tree.root!.Hash;
}

private static void DepthFirstSearch(MerkleTreeNode node, IList<UInt256> hashes)
Expand All @@ -100,7 +100,7 @@ private static void DepthFirstSearch(MerkleTreeNode node, IList<UInt256> hashes)
else
{
DepthFirstSearch(node.LeftChild, hashes);
DepthFirstSearch(node.RightChild, hashes);
DepthFirstSearch(node.RightChild!, hashes);
}
}

Expand Down Expand Up @@ -145,8 +145,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;
Expand Down
8 changes: 4 additions & 4 deletions src/Neo/Cryptography/MerkleTreeNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ namespace Neo.Cryptography
{
internal class MerkleTreeNode
{
public UInt256 Hash;
public MerkleTreeNode Parent;
public MerkleTreeNode LeftChild;
public MerkleTreeNode RightChild;
public UInt256 Hash = null!;
public MerkleTreeNode? Parent;
public MerkleTreeNode? LeftChild;
public MerkleTreeNode? RightChild;

public bool IsLeaf => LeftChild == null && RightChild == null;

Expand Down
30 changes: 25 additions & 5 deletions src/Neo/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,19 +135,19 @@ internal static void Remove<T, V>(this HashSet<T> set, IReadOnlyDictionary<T, V>

internal static string GetVersion(this Assembly assembly)
{
CustomAttributeData attribute = assembly.CustomAttributes.FirstOrDefault(p => p.AttributeType == typeof(AssemblyInformationalVersionAttribute));
if (attribute == null) return assembly.GetName().Version.ToString(3);
return (string)attribute.ConstructorArguments[0].Value;
CustomAttributeData? attribute = assembly.CustomAttributes.FirstOrDefault(p => p.AttributeType == typeof(AssemblyInformationalVersionAttribute));
if (attribute == null) return assembly.GetName().Version!.ToString(3);
return (string)attribute.ConstructorArguments[0].Value!;
}

/// <summary>
/// Converts a hex <see cref="string"/> to byte array.
/// </summary>
/// <param name="value">The hex <see cref="string"/> to convert.</param>
/// <returns>The converted byte array.</returns>
public static byte[] HexToBytes(this string value)
public static byte[] HexToBytes(this string? value)
{
if (value == null || value.Length == 0)
if (string.IsNullOrEmpty(value))
return Array.Empty<byte>();
if (value.Length % 2 == 1)
throw new FormatException();
Expand Down Expand Up @@ -309,5 +309,25 @@ internal static IPEndPoint Unmap(this IPEndPoint endPoint)
return endPoint;
return new IPEndPoint(endPoint.Address.Unmap(), endPoint.Port);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static T NullExceptionOr<T>(this object? obj) where T : class
{
if (obj == null) throw new NullReferenceException($"Object {nameof(obj)} is null.");
return (T)obj;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static T NotNull<T>(this T? obj) where T : class
{
return obj.NotNull($"Object {nameof(obj)} is null.");
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static T NotNull<T>(this T? obj, string msg) where T : class
{
if (obj == null) throw new NullReferenceException(msg);
return obj;
}
}
}
8 changes: 7 additions & 1 deletion src/Neo/IO/ByteArrayComparer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,14 @@ private ByteArrayComparer(int direction)
this.direction = direction;
}

public int Compare(byte[] x, byte[] y)
public int Compare(byte[]? x, byte[]? y)
{
if (x == null || y == null)
{
if (x == null && y == null) return 0;
return x == null ? -1 : 1;
}

return direction > 0
? CompareInternal(x, y)
: -CompareInternal(x, y);
Expand Down
2 changes: 1 addition & 1 deletion src/Neo/IO/ByteArrayEqualityComparer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ internal class ByteArrayEqualityComparer : IEqualityComparer<byte[]>
{
public static readonly ByteArrayEqualityComparer Default = new();

public unsafe bool Equals(byte[] x, byte[] y)
public unsafe bool Equals(byte[]? x, byte[]? y)
{
if (ReferenceEquals(x, y)) return true;
if (x is null || y is null) return false;
Expand Down
Loading