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

3.0.3 to 3.1.0 Comparison #12

Open
wants to merge 7 commits into
base: mainnet-3.0.3-untouched
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 2 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
pull_request:

env:
DOTNET_VERSION: 5.0.100
DOTNET_VERSION: 6.0.x

jobs:

Expand All @@ -21,8 +21,7 @@ jobs:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Check format
run: |
dotnet tool install --version 5.0.142902 --tool-path ./ dotnet-format --add-source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json
./dotnet-format --check -v diagnostic
dotnet format --verify-no-changes --verbosity diagnostic
- name: Test
run: |
find tests -name *.csproj | xargs -I % dotnet add % package coverlet.msbuild
Expand Down
28 changes: 24 additions & 4 deletions src/neo/Cryptography/ECC/ECPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
// modifications are permitted.

using Neo.IO;
using Neo.IO.Caching;
using System;
using System.IO;
using System.Numerics;
Expand All @@ -35,6 +36,9 @@ 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);

/// <summary>
/// Initializes a new instance of the <see cref="ECPoint"/> class with the secp256r1 curve.
/// </summary>
Expand Down Expand Up @@ -74,10 +78,7 @@ public static ECPoint DecodePoint(ReadOnlySpan<byte> encoded, ECCurve curve)
{
if (encoded.Length != (curve.ExpectedECPointLength + 1))
throw new FormatException("Incorrect length for compressed encoding");
int yTilde = encoded[0] & 1;
BigInteger X1 = new(encoded[1..], isUnsigned: true, isBigEndian: true);
p = DecompressPoint(yTilde, X1, curve);
p._compressedPoint = encoded.ToArray();
p = DecompressPoint(encoded, curve);
break;
}
case 0x04: // uncompressed
Expand All @@ -98,6 +99,25 @@ public static ECPoint DecodePoint(ReadOnlySpan<byte> encoded, ECCurve curve)
return p;
}

private static ECPoint DecompressPoint(ReadOnlySpan<byte> encoded, ECCurve curve)
{
ECPointCache pointCache = null;
if (curve == ECCurve.Secp256k1) pointCache = pointCacheK1;
else if (curve == ECCurve.Secp256r1) pointCache = pointCacheR1;
else throw new FormatException("Invalid curve " + curve);

byte[] compressedPoint = encoded.ToArray();
if (!pointCache.TryGet(compressedPoint, out ECPoint p))
{
int yTilde = encoded[0] & 1;
BigInteger X1 = new(encoded[1..], isUnsigned: true, isBigEndian: true);
p = DecompressPoint(yTilde, X1, curve);
p._compressedPoint = compressedPoint;
pointCache.Add(p);
}
return p;
}

private static ECPoint DecompressPoint(int yTilde, BigInteger X1, ECCurve curve)
{
ECFieldElement x = new(X1, curve);
Expand Down
5 changes: 3 additions & 2 deletions src/neo/IO/Caching/Cache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public CacheItem(TKey key, TValue value)
}

protected readonly ReaderWriterLockSlim RwSyncRootLock = new(LockRecursionPolicy.SupportsRecursion);
protected readonly Dictionary<TKey, CacheItem> InnerDictionary = new();
protected readonly Dictionary<TKey, CacheItem> InnerDictionary;
private readonly int max_capacity;

public TValue this[TKey key]
Expand Down Expand Up @@ -72,9 +72,10 @@ public int Count

public bool IsReadOnly => false;

public Cache(int max_capacity)
public Cache(int max_capacity, IEqualityComparer<TKey> comparer = null)
{
this.max_capacity = max_capacity;
this.InnerDictionary = new Dictionary<TKey, CacheItem>(comparer);
}

public void Add(TValue item)
Expand Down
27 changes: 27 additions & 0 deletions src/neo/IO/Caching/ECPointCache.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (C) 2015-2021 The Neo Project.
//
// The neo is free software distributed under the MIT software license,
// see the accompanying file LICENSE in the main directory of the
// project or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using Neo.Cryptography.ECC;

namespace Neo.IO.Caching
{
internal class ECPointCache : FIFOCache<byte[], ECPoint>
{
public ECPointCache(int max_capacity)
: base(max_capacity, ByteArrayEqualityComparer.Default)
{
}

protected override byte[] GetKeyForItem(ECPoint item)
{
return item.EncodePoint(true);
}
}
}
6 changes: 4 additions & 2 deletions src/neo/IO/Caching/FIFOCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using System.Collections.Generic;

namespace Neo.IO.Caching
{
internal abstract class FIFOCache<TKey, TValue> : Cache<TKey, TValue>
{
public FIFOCache(int max_capacity)
: base(max_capacity)
public FIFOCache(int max_capacity, IEqualityComparer<TKey> comparer = null)
: base(max_capacity, comparer)
{
}

Expand Down
35 changes: 35 additions & 0 deletions src/neo/IO/Caching/Tree.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (C) 2015-2021 The Neo Project.
//
// The neo is free software distributed under the MIT software license,
// see the accompanying file LICENSE in the main directory of the
// project or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using System;
using System.Collections.Generic;

namespace Neo.IO.Caching
{
public class Tree<T>
{
public TreeNode<T> Root { get; private set; }

public TreeNode<T> AddRoot(T item)
{
if (Root is not null)
throw new InvalidOperationException();
Root = new TreeNode<T>(item, null);
return Root;
}

public IEnumerable<T> GetItems()
{
if (Root is null) yield break;
foreach (T item in Root.GetItems())
yield return item;
}
}
}
43 changes: 43 additions & 0 deletions src/neo/IO/Caching/TreeNode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (C) 2015-2021 The Neo Project.
//
// The neo is free software distributed under the MIT software license,
// see the accompanying file LICENSE in the main directory of the
// project or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using System.Collections.Generic;

namespace Neo.IO.Caching
{
public class TreeNode<T>
{
public T Item { get; }
public TreeNode<T> Parent { get; }

private readonly List<TreeNode<T>> children = new();

internal TreeNode(T item, TreeNode<T> parent)
{
Item = item;
Parent = parent;
}

public TreeNode<T> AddChild(T item)
{
TreeNode<T> child = new(item, this);
children.Add(child);
return child;
}

internal IEnumerable<T> GetItems()
{
yield return Item;
foreach (var child in children)
foreach (T item in child.GetItems())
yield return item;
}
}
}
28 changes: 16 additions & 12 deletions src/neo/Ledger/Blockchain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -270,14 +270,15 @@ private VerifyResult OnNewBlock(Block block)
}

int blocksPersisted = 0;
// 15000 is the default among of seconds per block, while MilliSecondsPerBlock is the current
uint extraBlocks = (15000 - system.Settings.MillisecondsPerBlock) / 1000;
uint extraRelayingBlocks = system.Settings.MillisecondsPerBlock < ProtocolSettings.Default.MillisecondsPerBlock
? (ProtocolSettings.Default.MillisecondsPerBlock - system.Settings.MillisecondsPerBlock) / 1000
: 0;
foreach (Block blockToPersist in blocksToPersistList)
{
block_cache_unverified.Remove(blockToPersist.Index);
Persist(blockToPersist);

if (blocksPersisted++ < blocksToPersistList.Count - (2 + Math.Max(0, extraBlocks))) continue;
if (blocksPersisted++ < blocksToPersistList.Count - (2 + extraRelayingBlocks)) continue;
// Empirically calibrated for relaying the most recent 2 blocks persisted with 15s network
// Increase in the rate of 1 block per second in configurations with faster blocks

Expand All @@ -303,17 +304,20 @@ private VerifyResult OnNewBlock(Block block)

private void OnNewHeaders(Header[] headers)
{
if (system.HeaderCache.Full) return;
DataCache snapshot = system.StoreView;
uint headerHeight = system.HeaderCache.Last?.Index ?? NativeContract.Ledger.CurrentIndex(snapshot);
foreach (Header header in headers)
if (!system.HeaderCache.Full)
{
if (header.Index > headerHeight + 1) break;
if (header.Index < headerHeight + 1) continue;
if (!header.Verify(system.Settings, snapshot, system.HeaderCache)) break;
system.HeaderCache.Add(header);
++headerHeight;
DataCache snapshot = system.StoreView;
uint headerHeight = system.HeaderCache.Last?.Index ?? NativeContract.Ledger.CurrentIndex(snapshot);
foreach (Header header in headers)
{
if (header.Index > headerHeight + 1) break;
if (header.Index < headerHeight + 1) continue;
if (!header.Verify(system.Settings, snapshot, system.HeaderCache)) break;
system.HeaderCache.Add(header);
++headerHeight;
}
}
system.TaskManager.Tell(headers, Sender);
}

private VerifyResult OnNewExtensiblePayload(ExtensiblePayload payload)
Expand Down
20 changes: 20 additions & 0 deletions src/neo/Ledger/VerifyResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,26 @@ public enum VerifyResult : byte
/// </summary>
Invalid,

/// <summary>
/// Indicates that the <see cref="Transaction"/> has an invalid script.
/// </summary>
InvalidScript,

/// <summary>
/// Indicates that the <see cref="Transaction"/> has an invalid attribute.
/// </summary>
InvalidAttribute,

/// <summary>
/// Indicates that the <see cref="IInventory"/> has an invalid signature.
/// </summary>
InvalidSignature,

/// <summary>
/// Indicates that the size of the <see cref="IInventory"/> is not allowed.
/// </summary>
OverSize,

/// <summary>
/// Indicates that the <see cref="Transaction"/> has expired.
/// </summary>
Expand Down
57 changes: 57 additions & 0 deletions src/neo/Network/P2P/Payloads/Conditions/AndCondition.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright (C) 2015-2021 The Neo Project.
//
// The neo is free software distributed under the MIT software license,
// see the accompanying file LICENSE in the main directory of the
// project or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using Neo.IO;
using Neo.IO.Json;
using Neo.SmartContract;
using System;
using System.IO;
using System.Linq;

namespace Neo.Network.P2P.Payloads.Conditions
{
/// <summary>
/// Represents the condition that all conditions must be met.
/// </summary>
public class AndCondition : WitnessCondition
{
/// <summary>
/// The expressions of the condition.
/// </summary>
public WitnessCondition[] Expressions;

public override int Size => base.Size + Expressions.GetVarSize();
public override WitnessConditionType Type => WitnessConditionType.And;

protected override void DeserializeWithoutType(BinaryReader reader, int maxNestDepth)
{
if (maxNestDepth <= 0) throw new FormatException();
Expressions = DeserializeConditions(reader, maxNestDepth - 1);
if (Expressions.Length == 0) throw new FormatException();
}

public override bool Match(ApplicationEngine engine)
{
return Expressions.All(p => p.Match(engine));
}

protected override void SerializeWithoutType(BinaryWriter writer)
{
writer.Write(Expressions);
}

public override JObject ToJson()
{
JObject json = base.ToJson();
json["expressions"] = Expressions.Select(p => p.ToJson()).ToArray();
return json;
}
}
}
Loading