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

Allow Native Contracts to be updated #2942

Merged
merged 64 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
24b181f
Update manifest
shargon Nov 5, 2023
3c6a1f0
Fix comment
shargon Nov 5, 2023
a5772bc
Format & fix methods
shargon Nov 5, 2023
95335e0
Fix new
shargon Nov 5, 2023
7ae51e1
Initialize storage fixes
shargon Nov 5, 2023
22d72b5
Fix IsInitializeBlock
shargon Nov 5, 2023
c7602c6
Fix update
shargon Nov 5, 2023
b573a00
Fix GetContractState
shargon Nov 5, 2023
3adddd2
Optimize
shargon Nov 5, 2023
984d3d7
Fix first invoke without sync
shargon Nov 5, 2023
6341bad
Remove current methods
shargon Nov 6, 2023
4f59c43
Clean usings
shargon Nov 6, 2023
c85a1cc
Improve reading Initialize
shargon Nov 6, 2023
2490280
Clean OnManifestCompose
shargon Nov 6, 2023
47317ee
Use cache for all native contracts
shargon Nov 6, 2023
8fd8fc2
Fix ut
shargon Nov 6, 2023
7ba6274
Move cache to ApplicationEngine
shargon Nov 6, 2023
67a9364
Clean code
shargon Nov 6, 2023
8eb82db
Allow nullable attribute
shargon Nov 6, 2023
8667047
Update src/Neo/SmartContract/Native/ContractEventAttribute.cs
Jim8y Nov 6, 2023
5f41acf
Merge branch 'master' into update-native-contracts
Jim8y Nov 7, 2023
ed33b32
Add base call
shargon Nov 7, 2023
eea7324
Merge branch 'update-native-contracts' of https://github.com/neo-proj…
shargon Nov 7, 2023
594c2e6
Fix one https://github.com/neo-project/neo/pull/2941#discussion_r1382…
shargon Nov 7, 2023
64e5cfc
Fix IsInitializeBlock https://github.com/neo-project/neo/pull/2941#di…
shargon Nov 7, 2023
1b210ce
Add ContractEventAttribute constructors for ActiveIn
shargon Nov 7, 2023
5bb42d2
Merge branch 'master' into update-native-contracts
shargon Nov 8, 2023
690b5d4
Ensure ommited hfs
shargon Nov 8, 2023
8cef6ce
Rename
shargon Nov 8, 2023
f114982
Case insensitive hf config
shargon Nov 8, 2023
4e27f15
Merge branch 'master' into update-native-contracts
Jim8y Nov 8, 2023
1fee32f
Increase coverage
shargon Nov 9, 2023
957a507
Merge branch 'update-native-contracts' of https://github.com/neo-proj…
shargon Nov 9, 2023
06f1b23
More uts
shargon Nov 9, 2023
aee4be3
Rename
shargon Nov 9, 2023
c4b4a88
Update src/Neo/SmartContract/Native/ContractManagement.cs
shargon Nov 9, 2023
c5ebf3f
Merge branch 'master' into update-native-contracts
shargon Nov 9, 2023
28ac4e6
format code
shargon Nov 10, 2023
ff852a3
Fix ProtocolSettings
shargon Nov 10, 2023
f2586ed
Merge branch 'master' into update-native-contracts
shargon Nov 10, 2023
53e15b3
Merge branch 'master' into update-native-contracts
shargon Nov 11, 2023
8b4d596
Merge branch 'master' into update-native-contracts
shargon Dec 7, 2023
405a816
Update src/Neo/SmartContract/ApplicationEngine.cs
shargon Dec 11, 2023
4f9739d
Merge branch 'master' into update-native-contracts
shargon Jan 2, 2024
d621476
format
shargon Jan 2, 2024
4ade232
reorder using
shargon Jan 2, 2024
baa7807
Merge branch 'master' into update-native-contracts
Jim8y Jan 3, 2024
487f4ac
Fix UT
shargon Jan 3, 2024
963c557
Merge branch 'master' into update-native-contracts
shargon Jan 11, 2024
8c9e0c6
Adding keccak256 (#2925)
Jim8y Jan 11, 2024
7a8bb33
Merge branch 'master' into update-native-contracts
Jim8y Feb 4, 2024
d45fc30
Merge branch 'master' into update-native-contracts
shargon Feb 7, 2024
c7f0209
Merge branch 'master' into update-native-contracts
shargon Feb 7, 2024
6b0916d
Merge branch 'master' into update-native-contracts
shargon Feb 8, 2024
c13575c
Fix net standard
shargon Feb 8, 2024
5940271
Merge branch 'master' into update-native-contracts
Jim8y Feb 12, 2024
48d2349
Merge branch 'master' into update-native-contracts
shargon Feb 18, 2024
41914d8
Add ut
shargon Feb 19, 2024
e87e2b2
Fix update
shargon Feb 19, 2024
447583f
Merge branch 'master' into update-native-contracts
shargon Feb 20, 2024
d00f510
Merge branch 'master' into update-native-contracts
shargon Feb 21, 2024
8bcda87
Fix update
shargon Feb 21, 2024
40c5d97
Merge branch 'master' into update-native-contracts
shargon Feb 23, 2024
ef43618
Merge branch 'master' into update-native-contracts
shargon Feb 23, 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
34 changes: 34 additions & 0 deletions src/Neo/ProtocolSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ namespace Neo
/// </summary>
public record ProtocolSettings
{
private static readonly IList<Hardfork> AllHardforks = Enum.GetValues(typeof(Hardfork)).Cast<Hardfork>().ToArray();

/// <summary>
/// The magic number of the NEO network.
/// </summary>
Expand Down Expand Up @@ -220,5 +222,37 @@ private static void CheckingHardfork(ProtocolSettings settings)
}
}
}

/// <summary>
/// Check if the Hardfork is Enabled
/// </summary>
/// <param name="hardfork">Hardfork</param>
/// <param name="index">Block index</param>
/// <returns>True if enabled</returns>
public bool IsHardforkEnabled(Hardfork hardfork, uint index)
{
// Return true if there's no specific configuration
if (Hardforks.Count == 0)
return true;

// If the hardfork isn't specified in the configuration, check if it's a new one.
if (!Hardforks.ContainsKey(hardfork))
{
int currentHardforkIndex = AllHardforks.IndexOf(hardfork);
int lastConfiguredHardforkIndex = AllHardforks.IndexOf(Hardforks.Keys.Last());

// If it's a newer hardfork compared to the ones in the configuration, disable it.
if (currentHardforkIndex > lastConfiguredHardforkIndex)
return false;
}

if (Hardforks.TryGetValue(hardfork, out uint height))
shargon marked this conversation as resolved.
Show resolved Hide resolved
{
// If the hardfork has a specific height in the configuration, check the block height.
return index >= height;
}
// If no specific conditions are met, return true.
return true;
}
}
}
24 changes: 3 additions & 21 deletions src/Neo/SmartContract/ApplicationEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ public partial class ApplicationEngine : ExecutionEngine
/// </summary>
public static event EventHandler<LogEventArgs> Log;

private static readonly IList<Hardfork> AllHardforks = Enum.GetValues(typeof(Hardfork)).Cast<Hardfork>().ToArray();
private static Dictionary<uint, InteropDescriptor> services;
private readonly long gas_amount;
private Dictionary<Type, object> states;
Expand Down Expand Up @@ -613,28 +612,11 @@ public void SetState<T>(T state)

public bool IsHardforkEnabled(Hardfork hardfork)
{
// Return true if there's no specific configuration or PersistingBlock is null
if (PersistingBlock is null || ProtocolSettings.Hardforks.Count == 0)
// Return true if PersistingBlock is null
if (PersistingBlock is null)
return true;
shargon marked this conversation as resolved.
Show resolved Hide resolved

// If the hardfork isn't specified in the configuration, check if it's a new one.
if (!ProtocolSettings.Hardforks.ContainsKey(hardfork))
{
int currentHardforkIndex = AllHardforks.IndexOf(hardfork);
int lastConfiguredHardforkIndex = AllHardforks.IndexOf(ProtocolSettings.Hardforks.Keys.Last());

// If it's a newer hardfork compared to the ones in the configuration, disable it.
if (currentHardforkIndex > lastConfiguredHardforkIndex)
return false;
}

if (ProtocolSettings.Hardforks.TryGetValue(hardfork, out uint height))
{
// If the hardfork has a specific height in the configuration, check the block height.
return PersistingBlock.Index >= height;
}
// If no specific conditions are met, return true.
return true;
return ProtocolSettings.IsHardforkEnabled(hardfork, PersistingBlock.Index);
}
}
}
134 changes: 134 additions & 0 deletions src/Neo/SmartContract/Native/ContractEventAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
// Copyright (C) 2015-2022 The Neo Project.
Jim8y marked this conversation as resolved.
Show resolved Hide resolved
//
// 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.Diagnostics;
using Neo.SmartContract.Manifest;

namespace Neo.SmartContract.Native
{
[DebuggerDisplay("{Descriptor.Name}")]
[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = true)]
internal class ContractEventAttribute : Attribute
{
public int Order { get; init; }
public ContractEventDescriptor Descriptor { get; set; }
public Hardfork? ActiveIn { get; init; } = null;

public ContractEventAttribute(int order, string name, string arg1Name, ContractParameterType arg1Value)
{
Order = order;
Descriptor = new ContractEventDescriptor()
{
Name = name,
Parameters = new ContractParameterDefinition[]
{
new ContractParameterDefinition()
{
Name = arg1Name,
Type = arg1Value
}
}
};
}

public ContractEventAttribute(int order, string name,
string arg1Name, ContractParameterType arg1Value,
string arg2Name, ContractParameterType arg2Value)
{
Order = order;
Descriptor = new ContractEventDescriptor()
{
Name = name,
Parameters = new ContractParameterDefinition[]
{
new ContractParameterDefinition()
{
Name = arg1Name,
Type = arg1Value
},
new ContractParameterDefinition()
{
Name = arg2Name,
Type = arg2Value
}
}
};
}

public ContractEventAttribute(int order, string name,
string arg1Name, ContractParameterType arg1Value,
string arg2Name, ContractParameterType arg2Value,
string arg3Name, ContractParameterType arg3Value
)
{
Order = order;
Descriptor = new ContractEventDescriptor()
{
Name = name,
Parameters = new ContractParameterDefinition[]
{
new ContractParameterDefinition()
{
Name = arg1Name,
Type = arg1Value
},
new ContractParameterDefinition()
{
Name = arg2Name,
Type = arg2Value
},
new ContractParameterDefinition()
{
Name = arg3Name,
Type = arg3Value
}
}
};
}

public ContractEventAttribute(int order, string name,
string arg1Name, ContractParameterType arg1Value,
string arg2Name, ContractParameterType arg2Value,
string arg3Name, ContractParameterType arg3Value,
string arg4Name, ContractParameterType arg4Value
)
{
Order = order;
Descriptor = new ContractEventDescriptor()
{
Name = name,
Parameters = new ContractParameterDefinition[]
{
new ContractParameterDefinition()
{
Name = arg1Name,
Type = arg1Value
},
new ContractParameterDefinition()
{
Name = arg2Name,
Type = arg2Value
},
new ContractParameterDefinition()
{
Name = arg3Name,
Type = arg3Value
},
new ContractParameterDefinition()
{
Name = arg4Name,
Type = arg4Value
}
}
};
}
}
}
94 changes: 33 additions & 61 deletions src/Neo/SmartContract/Native/ContractManagement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@

#pragma warning disable IDE0051

using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using Neo.IO;
using Neo.Network.P2P.Payloads;
using Neo.Persistence;
using Neo.SmartContract.Iterators;
using Neo.SmartContract.Manifest;
using Neo.VM.Types;
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;

namespace Neo.SmartContract.Native
{
Expand All @@ -34,50 +34,10 @@ public sealed class ContractManagement : NativeContract
private const byte Prefix_Contract = 8;
private const byte Prefix_ContractHash = 12;

internal ContractManagement()
{
var events = new List<ContractEventDescriptor>(Manifest.Abi.Events)
{
new ContractEventDescriptor
{
Name = "Deploy",
Parameters = new ContractParameterDefinition[]
{
new ContractParameterDefinition()
{
Name = "Hash",
Type = ContractParameterType.Hash160
}
}
},
new ContractEventDescriptor
{
Name = "Update",
Parameters = new ContractParameterDefinition[]
{
new ContractParameterDefinition()
{
Name = "Hash",
Type = ContractParameterType.Hash160
}
}
},
new ContractEventDescriptor
{
Name = "Destroy",
Parameters = new ContractParameterDefinition[]
{
new ContractParameterDefinition()
{
Name = "Hash",
Type = ContractParameterType.Hash160
}
}
}
};

Manifest.Abi.Events = events.ToArray();
}
[ContractEvent(0, name: "Deploy", "Hash", ContractParameterType.Hash160)]
vncoelho marked this conversation as resolved.
Show resolved Hide resolved
[ContractEvent(1, name: "Update", "Hash", ContractParameterType.Hash160)]
[ContractEvent(2, name: "Destroy", "Hash", ContractParameterType.Hash160)]
internal ContractManagement() : base() { }

private int GetNextAvailableId(DataCache snapshot)
{
Expand All @@ -87,10 +47,13 @@ private int GetNextAvailableId(DataCache snapshot)
return value;
}

internal override ContractTask Initialize(ApplicationEngine engine)
internal override ContractTask Initialize(ApplicationEngine engine, Hardfork? hardfork)
{
engine.Snapshot.Add(CreateStorageKey(Prefix_MinimumDeploymentFee), new StorageItem(10_00000000));
engine.Snapshot.Add(CreateStorageKey(Prefix_NextAvailableId), new StorageItem(1));
if (hardfork == ActiveIn)
{
engine.Snapshot.Add(CreateStorageKey(Prefix_MinimumDeploymentFee), new StorageItem(10_00000000));
engine.Snapshot.Add(CreateStorageKey(Prefix_NextAvailableId), new StorageItem(1));
}
return ContractTask.CompletedTask;
}

Expand All @@ -106,17 +69,26 @@ internal override async ContractTask OnPersist(ApplicationEngine engine)
{
foreach (NativeContract contract in Contracts)
{
if (contract.IsInitializeBlock(engine.ProtocolSettings, engine.PersistingBlock.Index))
if (contract.IsInitializeBlock(engine.ProtocolSettings, engine.PersistingBlock.Index, out Hardfork? hf))
{
engine.Snapshot.Add(CreateStorageKey(Prefix_Contract).Add(contract.Hash), new StorageItem(new ContractState
ContractState contractState = contract.GetContractState(engine.ProtocolSettings, engine.PersistingBlock.Index);
StorageItem state = engine.Snapshot.TryGet(CreateStorageKey(Prefix_Contract).Add(contract.Hash));

if (state is null)
{
Id = contract.Id,
Nef = contract.Nef,
Hash = contract.Hash,
Manifest = contract.Manifest
}));
engine.Snapshot.Add(CreateStorageKey(Prefix_ContractHash).AddBigEndian(contract.Id), new StorageItem(contract.Hash.ToArray()));
await contract.Initialize(engine);
// Create the contract state
engine.Snapshot.Add(CreateStorageKey(Prefix_Contract).Add(contract.Hash), new StorageItem(contractState));
engine.Snapshot.Add(CreateStorageKey(Prefix_ContractHash).AddBigEndian(contract.Id), new StorageItem(contract.Hash.ToArray()));
}
else
{
// Increase the update counter
contractState.UpdateCounter = (ushort)(state.GetInteroperable<ContractState>().UpdateCounter + 1);
vncoelho marked this conversation as resolved.
Show resolved Hide resolved
// Update the contract state
state.Set(contractState);
}

await contract.Initialize(engine, hf);
shargon marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/Neo/SmartContract/Native/ContractMethodAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,18 @@
// modifications are permitted.

using System;
using System.Diagnostics;

namespace Neo.SmartContract.Native
{
[DebuggerDisplay("{Name}")]
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = false)]
internal class ContractMethodAttribute : Attribute
{
public string Name { get; init; }
public CallFlags RequiredCallFlags { get; init; }
public long CpuFee { get; init; }
public long StorageFee { get; init; }
public Hardfork? ActiveIn { get; init; } = null;
shargon marked this conversation as resolved.
Show resolved Hide resolved
}
}
Loading