diff --git a/src/Neo.CLI/CLI/MainService.Blockchain.cs b/src/Neo.CLI/CLI/MainService.Blockchain.cs index 2ac9c46ea4..8f6af73678 100644 --- a/src/Neo.CLI/CLI/MainService.Blockchain.cs +++ b/src/Neo.CLI/CLI/MainService.Blockchain.cs @@ -193,12 +193,12 @@ public void OnShowTransactionCommand(UInt256 hash) { switch (attribute) { - case Conflicts c: + case ConflictsAttribute c: ConsoleHelper.Info("", " Type: ", $"{c.Type}"); ConsoleHelper.Info("", " Hash: ", $"{c.Hash}"); ConsoleHelper.Info("", " Size: ", $"{c.Size} Byte(s)"); break; - case OracleResponse o: + case OracleResponseAttribute o: ConsoleHelper.Info("", " Type: ", $"{o.Type}"); ConsoleHelper.Info("", " Id: ", $"{o.Id}"); ConsoleHelper.Info("", " Code: ", $"{o.Code}"); @@ -208,7 +208,7 @@ public void OnShowTransactionCommand(UInt256 hash) case HighPriorityAttribute p: ConsoleHelper.Info("", " Type: ", $"{p.Type}"); break; - case NotValidBefore n: + case NotValidBeforeAttribute n: ConsoleHelper.Info("", " Type: ", $"{n.Type}"); ConsoleHelper.Info("", " Height: ", $"{n.Height}"); break; diff --git a/src/Neo.CLI/CLI/MainService.Wallet.cs b/src/Neo.CLI/CLI/MainService.Wallet.cs index 54bd8dccab..534854eeef 100644 --- a/src/Neo.CLI/CLI/MainService.Wallet.cs +++ b/src/Neo.CLI/CLI/MainService.Wallet.cs @@ -581,7 +581,7 @@ private void OnCancelCommand(UInt256 txid, UInt160? sender = null, UInt160[]? si return; } - var conflict = new TransactionAttribute[] { new Conflicts() { Hash = txid } }; + var conflict = new TransactionAttribute[] { new ConflictsAttribute() { Hash = txid } }; Signer[] signers = Array.Empty(); if (sender != null) { diff --git a/src/Neo/Ledger/MemoryPool.cs b/src/Neo/Ledger/MemoryPool.cs index 8f9437641b..0acd7c7bca 100644 --- a/src/Neo/Ledger/MemoryPool.cs +++ b/src/Neo/Ledger/MemoryPool.cs @@ -317,7 +317,7 @@ internal VerifyResult TryAdd(Transaction tx, DataCache snapshot) VerificationContext.RemoveTransaction(conflict.Tx); } removedTransactions = conflictsToBeRemoved.Select(itm => itm.Tx).ToList(); - foreach (var attr in tx.GetAttributes()) + foreach (var attr in tx.GetAttributes()) { if (!_conflicts.TryGetValue(attr.Hash, out var pooled)) { @@ -371,7 +371,7 @@ private bool CheckConflicts(Transaction tx, out List conflictsList) } } // Step 2: check if unsorted transactions were in `tx`'s Conflicts attributes. - foreach (var hash in tx.GetAttributes().Select(p => p.Hash)) + foreach (var hash in tx.GetAttributes().Select(p => p.Hash)) { if (_unsortedTransactions.TryGetValue(hash, out var unsortedTx)) { @@ -429,7 +429,7 @@ private bool TryRemoveVerified(UInt256 hash, [MaybeNullWhen(false)] out PoolItem [MethodImpl(MethodImplOptions.AggressiveInlining)] private void RemoveConflictsOfVerified(PoolItem item) { - foreach (var h in item.Tx.GetAttributes().Select(attr => attr.Hash)) + foreach (var h in item.Tx.GetAttributes().Select(attr => attr.Hash)) { if (_conflicts.TryGetValue(h, out var conflicts)) { @@ -483,7 +483,7 @@ internal void UpdatePoolForBlockPersisted(Block block, DataCache snapshot) { if (!TryRemoveVerified(tx.Hash, out _)) TryRemoveUnVerified(tx.Hash, out _); var conflictingSigners = tx.Signers.Select(s => s.Account); - foreach (var h in tx.GetAttributes().Select(a => a.Hash)) + foreach (var h in tx.GetAttributes().Select(a => a.Hash)) { if (conflicts.TryGetValue(h, out var signersList)) { @@ -501,7 +501,7 @@ internal void UpdatePoolForBlockPersisted(Block block, DataCache snapshot) var stale = new List(); foreach (var item in _sortedTransactions) { - if ((conflicts.TryGetValue(item.Tx.Hash, out var signersList) && signersList.Intersect(item.Tx.Signers.Select(s => s.Account)).Any()) || item.Tx.GetAttributes().Select(a => a.Hash).Intersect(persisted).Any()) + if ((conflicts.TryGetValue(item.Tx.Hash, out var signersList) && signersList.Intersect(item.Tx.Signers.Select(s => s.Account)).Any()) || item.Tx.GetAttributes().Select(a => a.Hash).Intersect(persisted).Any()) { stale.Add(item.Tx.Hash); conflictingItems.Add(item.Tx); @@ -569,7 +569,7 @@ private int ReverifyTransactions(SortedSet verifiedSortedTxPool, if (_unsortedTransactions.TryAdd(item.Tx.Hash, item)) { verifiedSortedTxPool.Add(item); - foreach (var attr in item.Tx.GetAttributes()) + foreach (var attr in item.Tx.GetAttributes()) { if (!_conflicts.TryGetValue(attr.Hash, out var pooled)) { diff --git a/src/Neo/Ledger/TransactionVerificationContext.cs b/src/Neo/Ledger/TransactionVerificationContext.cs index 2300c6da30..b149cb22d3 100644 --- a/src/Neo/Ledger/TransactionVerificationContext.cs +++ b/src/Neo/Ledger/TransactionVerificationContext.cs @@ -39,7 +39,7 @@ public class TransactionVerificationContext /// The verified . public void AddTransaction(Transaction tx) { - var oracle = tx.GetAttribute(); + var oracle = tx.GetAttribute(); if (oracle != null) oracleResponses.Add(oracle.Id, tx.Hash); if (senderFee.TryGetValue(tx.Sender, out var value)) @@ -65,7 +65,7 @@ public bool CheckTransaction(Transaction tx, IEnumerable conflictin expectedFee -= (conflictTx.NetworkFee + conflictTx.SystemFee); if (balance < expectedFee) return false; - var oracle = tx.GetAttribute(); + var oracle = tx.GetAttribute(); if (oracle != null && oracleResponses.ContainsKey(oracle.Id)) return false; @@ -80,7 +80,7 @@ public void RemoveTransaction(Transaction tx) { if ((senderFee[tx.Sender] -= tx.SystemFee + tx.NetworkFee) == 0) senderFee.Remove(tx.Sender); - var oracle = tx.GetAttribute(); + var oracle = tx.GetAttribute(); if (oracle != null) oracleResponses.Remove(oracle.Id); } } diff --git a/src/Neo/Network/P2P/ChannelsConfig.cs b/src/Neo/Network/P2P/Connection/ChannelsConfig.cs similarity index 100% rename from src/Neo/Network/P2P/ChannelsConfig.cs rename to src/Neo/Network/P2P/Connection/ChannelsConfig.cs diff --git a/src/Neo/Network/P2P/Connection.cs b/src/Neo/Network/P2P/Connection/Connection.cs similarity index 100% rename from src/Neo/Network/P2P/Connection.cs rename to src/Neo/Network/P2P/Connection/Connection.cs diff --git a/src/Neo/Network/P2P/LocalNode.cs b/src/Neo/Network/P2P/Connection/LocalNode.cs similarity index 100% rename from src/Neo/Network/P2P/LocalNode.cs rename to src/Neo/Network/P2P/Connection/LocalNode.cs diff --git a/src/Neo/Network/P2P/Message.cs b/src/Neo/Network/P2P/Connection/Message.cs similarity index 100% rename from src/Neo/Network/P2P/Message.cs rename to src/Neo/Network/P2P/Connection/Message.cs diff --git a/src/Neo/Network/P2P/MessageCommand.cs b/src/Neo/Network/P2P/Connection/MessageCommand.cs similarity index 100% rename from src/Neo/Network/P2P/MessageCommand.cs rename to src/Neo/Network/P2P/Connection/MessageCommand.cs diff --git a/src/Neo/Network/P2P/MessageFlags.cs b/src/Neo/Network/P2P/Connection/MessageFlags.cs similarity index 100% rename from src/Neo/Network/P2P/MessageFlags.cs rename to src/Neo/Network/P2P/Connection/MessageFlags.cs diff --git a/src/Neo/Network/P2P/Peer.cs b/src/Neo/Network/P2P/Connection/Peer.cs similarity index 100% rename from src/Neo/Network/P2P/Peer.cs rename to src/Neo/Network/P2P/Connection/Peer.cs diff --git a/src/Neo/Network/P2P/RemoteNode.ProtocolHandler.cs b/src/Neo/Network/P2P/Connection/RemoteNode.ProtocolHandler.cs similarity index 100% rename from src/Neo/Network/P2P/RemoteNode.ProtocolHandler.cs rename to src/Neo/Network/P2P/Connection/RemoteNode.ProtocolHandler.cs diff --git a/src/Neo/Network/P2P/RemoteNode.cs b/src/Neo/Network/P2P/Connection/RemoteNode.cs similarity index 100% rename from src/Neo/Network/P2P/RemoteNode.cs rename to src/Neo/Network/P2P/Connection/RemoteNode.cs diff --git a/src/Neo/Network/P2P/TaskManager.cs b/src/Neo/Network/P2P/Connection/TaskManager.cs similarity index 100% rename from src/Neo/Network/P2P/TaskManager.cs rename to src/Neo/Network/P2P/Connection/TaskManager.cs diff --git a/src/Neo/Network/P2P/TaskSession.cs b/src/Neo/Network/P2P/Connection/TaskSession.cs similarity index 100% rename from src/Neo/Network/P2P/TaskSession.cs rename to src/Neo/Network/P2P/Connection/TaskSession.cs diff --git a/src/Neo/Network/P2P/Payloads/Conflicts.cs b/src/Neo/Network/P2P/Payloads/TransactionAttributes/Conflicts.cs similarity index 96% rename from src/Neo/Network/P2P/Payloads/Conflicts.cs rename to src/Neo/Network/P2P/Payloads/TransactionAttributes/Conflicts.cs index 082de2014d..ed016912da 100644 --- a/src/Neo/Network/P2P/Payloads/Conflicts.cs +++ b/src/Neo/Network/P2P/Payloads/TransactionAttributes/Conflicts.cs @@ -13,10 +13,12 @@ using Neo.Json; using Neo.Persistence; using Neo.SmartContract.Native; +using System; using System.IO; namespace Neo.Network.P2P.Payloads { + [Obsolete("Use ConflictsAttribute instead")] public class Conflicts : TransactionAttribute { /// diff --git a/src/Neo/Network/P2P/Payloads/TransactionAttributes/ConflictsAttribute.cs b/src/Neo/Network/P2P/Payloads/TransactionAttributes/ConflictsAttribute.cs new file mode 100644 index 0000000000..da85764f8b --- /dev/null +++ b/src/Neo/Network/P2P/Payloads/TransactionAttributes/ConflictsAttribute.cs @@ -0,0 +1,63 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// ConflictsAttribute.cs file belongs to the neo project and is free +// software distributed under the MIT software license, see the +// accompanying file LICENSE in the main directory of the +// repository 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.Json; +using Neo.Persistence; +using Neo.SmartContract.Native; +using System.IO; + +namespace Neo.Network.P2P.Payloads +{ + public class ConflictsAttribute : TransactionAttribute + { + /// + /// Indicates the conflict transaction hash. + /// + public UInt256 Hash; + + public override TransactionAttributeType Type => TransactionAttributeType.Conflicts; + + public override bool AllowMultiple => true; + + public override int Size => base.Size + Hash.Size; + + protected override void DeserializeWithoutType(ref MemoryReader reader) + { + Hash = reader.ReadSerializable(); + } + + protected override void SerializeWithoutType(BinaryWriter writer) + { + writer.Write(Hash); + } + + public override JObject ToJson() + { + JObject json = base.ToJson(); + json["hash"] = Hash.ToString(); + return json; + } + + public override bool Verify(DataCache snapshot, Transaction tx) + { + // Only check if conflicting transaction is on chain. It's OK if the + // conflicting transaction was in the Conflicts attribute of some other + // on-chain transaction. + return !NativeContract.Ledger.ContainsTransaction(snapshot, Hash); + } + + public override long CalculateNetworkFee(DataCache snapshot, Transaction tx) + { + return tx.Signers.Length * base.CalculateNetworkFee(snapshot, tx); + } + } +} diff --git a/src/Neo/Network/P2P/Payloads/HighPriorityAttribute.cs b/src/Neo/Network/P2P/Payloads/TransactionAttributes/HighPriorityAttribute.cs similarity index 100% rename from src/Neo/Network/P2P/Payloads/HighPriorityAttribute.cs rename to src/Neo/Network/P2P/Payloads/TransactionAttributes/HighPriorityAttribute.cs diff --git a/src/Neo/Network/P2P/Payloads/NotValidBefore.cs b/src/Neo/Network/P2P/Payloads/TransactionAttributes/NotValidBefore.cs similarity index 92% rename from src/Neo/Network/P2P/Payloads/NotValidBefore.cs rename to src/Neo/Network/P2P/Payloads/TransactionAttributes/NotValidBefore.cs index 382a60e8fc..311455d4f7 100644 --- a/src/Neo/Network/P2P/Payloads/NotValidBefore.cs +++ b/src/Neo/Network/P2P/Payloads/TransactionAttributes/NotValidBefore.cs @@ -13,10 +13,12 @@ using Neo.Json; using Neo.Persistence; using Neo.SmartContract.Native; +using System; using System.IO; namespace Neo.Network.P2P.Payloads { + [Obsolete("Use NotValidBeforeAttribute instead")] public class NotValidBefore : TransactionAttribute { /// @@ -29,7 +31,7 @@ public class NotValidBefore : TransactionAttribute public override bool AllowMultiple => false; public override int Size => base.Size + - sizeof(uint); // Height. + sizeof(uint); // Height. protected override void DeserializeWithoutType(ref MemoryReader reader) { diff --git a/src/Neo/Network/P2P/Payloads/TransactionAttributes/NotValidBeforeAttribute.cs b/src/Neo/Network/P2P/Payloads/TransactionAttributes/NotValidBeforeAttribute.cs new file mode 100644 index 0000000000..f9341db3fc --- /dev/null +++ b/src/Neo/Network/P2P/Payloads/TransactionAttributes/NotValidBeforeAttribute.cs @@ -0,0 +1,57 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// NotValidBeforeAttribute.cs file belongs to the neo project and is free +// software distributed under the MIT software license, see the +// accompanying file LICENSE in the main directory of the +// repository 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.Json; +using Neo.Persistence; +using Neo.SmartContract.Native; +using System.IO; + +namespace Neo.Network.P2P.Payloads +{ + public class NotValidBeforeAttribute : TransactionAttribute + { + /// + /// Indicates that the transaction is not valid before this height. + /// + public uint Height; + + public override TransactionAttributeType Type => TransactionAttributeType.NotValidBefore; + + public override bool AllowMultiple => false; + + public override int Size => base.Size + + sizeof(uint); // Height. + + protected override void DeserializeWithoutType(ref MemoryReader reader) + { + Height = reader.ReadUInt32(); + } + + protected override void SerializeWithoutType(BinaryWriter writer) + { + writer.Write(Height); + } + + public override JObject ToJson() + { + JObject json = base.ToJson(); + json["height"] = Height; + return json; + } + + public override bool Verify(DataCache snapshot, Transaction tx) + { + var block_height = NativeContract.Ledger.CurrentIndex(snapshot); + return block_height >= Height; + } + } +} diff --git a/src/Neo/Network/P2P/Payloads/OracleResponse.cs b/src/Neo/Network/P2P/Payloads/TransactionAttributes/OracleResponse.cs similarity index 98% rename from src/Neo/Network/P2P/Payloads/OracleResponse.cs rename to src/Neo/Network/P2P/Payloads/TransactionAttributes/OracleResponse.cs index 2770f556a8..b7eeea2e7c 100644 --- a/src/Neo/Network/P2P/Payloads/OracleResponse.cs +++ b/src/Neo/Network/P2P/Payloads/TransactionAttributes/OracleResponse.cs @@ -24,6 +24,7 @@ namespace Neo.Network.P2P.Payloads /// /// Indicates that the transaction is an oracle response. /// + [Obsolete("Use OracleResponseAttribute instead")] public class OracleResponse : TransactionAttribute { /// diff --git a/src/Neo/Network/P2P/Payloads/TransactionAttributes/OracleResponseAttribute.cs b/src/Neo/Network/P2P/Payloads/TransactionAttributes/OracleResponseAttribute.cs new file mode 100644 index 0000000000..f76ef4a184 --- /dev/null +++ b/src/Neo/Network/P2P/Payloads/TransactionAttributes/OracleResponseAttribute.cs @@ -0,0 +1,107 @@ +// Copyright (C) 2015-2024 The Neo Project. +// +// OracleResponseAttribute.cs file belongs to the neo project and is free +// software distributed under the MIT software license, see the +// accompanying file LICENSE in the main directory of the +// repository 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.Json; +using Neo.Persistence; +using Neo.SmartContract; +using Neo.SmartContract.Native; +using Neo.VM; +using System; +using System.IO; +using System.Linq; + +namespace Neo.Network.P2P.Payloads +{ + /// + /// Indicates that the transaction is an oracle response. + /// + public class OracleResponseAttribute : TransactionAttribute + { + /// + /// Indicates the maximum size of the field. + /// + public const int MaxResultSize = ushort.MaxValue; + + /// + /// Represents the fixed value of the field of the oracle responding transaction. + /// + public static readonly byte[] FixedScript; + + /// + /// The ID of the oracle request. + /// + public ulong Id; + + /// + /// The response code for the oracle request. + /// + public OracleResponseCode Code; + + /// + /// The result for the oracle request. + /// + public ReadOnlyMemory Result; + + public override TransactionAttributeType Type => TransactionAttributeType.OracleResponse; + public override bool AllowMultiple => false; + + public override int Size => base.Size + + sizeof(ulong) + //Id + sizeof(OracleResponseCode) + //ResponseCode + Result.GetVarSize(); //Result + + static OracleResponseAttribute() + { + using ScriptBuilder sb = new(); + sb.EmitDynamicCall(NativeContract.Oracle.Hash, "finish"); + FixedScript = sb.ToArray(); + } + + protected override void DeserializeWithoutType(ref MemoryReader reader) + { + Id = reader.ReadUInt64(); + Code = (OracleResponseCode)reader.ReadByte(); + if (!Enum.IsDefined(typeof(OracleResponseCode), Code)) + throw new FormatException(); + Result = reader.ReadVarMemory(MaxResultSize); + if (Code != OracleResponseCode.Success && Result.Length > 0) + throw new FormatException(); + } + + protected override void SerializeWithoutType(BinaryWriter writer) + { + writer.Write(Id); + writer.Write((byte)Code); + writer.WriteVarBytes(Result.Span); + } + + public override JObject ToJson() + { + JObject json = base.ToJson(); + json["id"] = Id; + json["code"] = Code; + json["result"] = Convert.ToBase64String(Result.Span); + return json; + } + + 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); + 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)); + return tx.Signers.Any(p => p.Account.Equals(oracleAccount)); + } + } +} diff --git a/src/Neo/Network/P2P/Payloads/OracleResponseCode.cs b/src/Neo/Network/P2P/Payloads/TransactionAttributes/OracleResponseCode.cs similarity index 100% rename from src/Neo/Network/P2P/Payloads/OracleResponseCode.cs rename to src/Neo/Network/P2P/Payloads/TransactionAttributes/OracleResponseCode.cs diff --git a/src/Neo/Network/P2P/Payloads/TransactionAttribute.cs b/src/Neo/Network/P2P/Payloads/TransactionAttributes/TransactionAttribute.cs similarity index 100% rename from src/Neo/Network/P2P/Payloads/TransactionAttribute.cs rename to src/Neo/Network/P2P/Payloads/TransactionAttributes/TransactionAttribute.cs diff --git a/src/Neo/Network/P2P/Payloads/TransactionAttributeType.cs b/src/Neo/Network/P2P/Payloads/TransactionAttributes/TransactionAttributeType.cs similarity index 79% rename from src/Neo/Network/P2P/Payloads/TransactionAttributeType.cs rename to src/Neo/Network/P2P/Payloads/TransactionAttributes/TransactionAttributeType.cs index 116f136c07..11e5da07bb 100644 --- a/src/Neo/Network/P2P/Payloads/TransactionAttributeType.cs +++ b/src/Neo/Network/P2P/Payloads/TransactionAttributes/TransactionAttributeType.cs @@ -14,7 +14,7 @@ namespace Neo.Network.P2P.Payloads { /// - /// Represents the type of a . + /// Represents the type of . /// public enum TransactionAttributeType : byte { @@ -27,19 +27,19 @@ public enum TransactionAttributeType : byte /// /// Indicates that the transaction is an oracle response. /// - [ReflectionCache(typeof(OracleResponse))] + [ReflectionCache(typeof(OracleResponseAttribute))] OracleResponse = 0x11, /// - /// Indicates that the transaction is not valid before . + /// Indicates that the transaction is not valid before . /// - [ReflectionCache(typeof(NotValidBefore))] + [ReflectionCache(typeof(NotValidBeforeAttribute))] NotValidBefore = 0x20, /// - /// Indicates that the transaction conflicts with . + /// Indicates that the transaction conflicts with . /// - [ReflectionCache(typeof(Conflicts))] + [ReflectionCache(typeof(ConflictsAttribute))] Conflicts = 0x21 } } diff --git a/src/Neo/Network/P2P/Payloads/Block.cs b/src/Neo/Network/P2P/Payloads/Verifiables/Block.cs similarity index 100% rename from src/Neo/Network/P2P/Payloads/Block.cs rename to src/Neo/Network/P2P/Payloads/Verifiables/Block.cs diff --git a/src/Neo/Network/P2P/Payloads/ExtensiblePayload.cs b/src/Neo/Network/P2P/Payloads/Verifiables/ExtensiblePayload.cs similarity index 100% rename from src/Neo/Network/P2P/Payloads/ExtensiblePayload.cs rename to src/Neo/Network/P2P/Payloads/Verifiables/ExtensiblePayload.cs diff --git a/src/Neo/Network/P2P/Payloads/Header.cs b/src/Neo/Network/P2P/Payloads/Verifiables/Header.cs similarity index 100% rename from src/Neo/Network/P2P/Payloads/Header.cs rename to src/Neo/Network/P2P/Payloads/Verifiables/Header.cs diff --git a/src/Neo/Network/P2P/Payloads/IInventory.cs b/src/Neo/Network/P2P/Payloads/Verifiables/IInventory.cs similarity index 100% rename from src/Neo/Network/P2P/Payloads/IInventory.cs rename to src/Neo/Network/P2P/Payloads/Verifiables/IInventory.cs diff --git a/src/Neo/Network/P2P/Payloads/IVerifiable.cs b/src/Neo/Network/P2P/Payloads/Verifiables/IVerifiable.cs similarity index 100% rename from src/Neo/Network/P2P/Payloads/IVerifiable.cs rename to src/Neo/Network/P2P/Payloads/Verifiables/IVerifiable.cs diff --git a/src/Neo/Network/P2P/Payloads/InvPayload.cs b/src/Neo/Network/P2P/Payloads/Verifiables/InvPayload.cs similarity index 100% rename from src/Neo/Network/P2P/Payloads/InvPayload.cs rename to src/Neo/Network/P2P/Payloads/Verifiables/InvPayload.cs diff --git a/src/Neo/Network/P2P/Payloads/InventoryType.cs b/src/Neo/Network/P2P/Payloads/Verifiables/InventoryType.cs similarity index 100% rename from src/Neo/Network/P2P/Payloads/InventoryType.cs rename to src/Neo/Network/P2P/Payloads/Verifiables/InventoryType.cs diff --git a/src/Neo/Network/P2P/Payloads/Transaction.cs b/src/Neo/Network/P2P/Payloads/Verifiables/Transaction.cs similarity index 100% rename from src/Neo/Network/P2P/Payloads/Transaction.cs rename to src/Neo/Network/P2P/Payloads/Verifiables/Transaction.cs diff --git a/src/Neo/Network/P2P/Payloads/Witness.cs b/src/Neo/Network/P2P/Payloads/Witness/Witness.cs similarity index 100% rename from src/Neo/Network/P2P/Payloads/Witness.cs rename to src/Neo/Network/P2P/Payloads/Witness/Witness.cs diff --git a/src/Neo/Network/P2P/Payloads/WitnessRule.cs b/src/Neo/Network/P2P/Payloads/Witness/WitnessRule.cs similarity index 100% rename from src/Neo/Network/P2P/Payloads/WitnessRule.cs rename to src/Neo/Network/P2P/Payloads/Witness/WitnessRule.cs diff --git a/src/Neo/Network/P2P/Payloads/WitnessRuleAction.cs b/src/Neo/Network/P2P/Payloads/Witness/WitnessRuleAction.cs similarity index 100% rename from src/Neo/Network/P2P/Payloads/WitnessRuleAction.cs rename to src/Neo/Network/P2P/Payloads/Witness/WitnessRuleAction.cs diff --git a/src/Neo/Network/P2P/Payloads/WitnessScope.cs b/src/Neo/Network/P2P/Payloads/Witness/WitnessScope.cs similarity index 100% rename from src/Neo/Network/P2P/Payloads/WitnessScope.cs rename to src/Neo/Network/P2P/Payloads/Witness/WitnessScope.cs diff --git a/src/Neo/SmartContract/ApplicationEngine.Contract.cs b/src/Neo/SmartContract/ApplicationEngine/ApplicationEngine.Contract.cs similarity index 100% rename from src/Neo/SmartContract/ApplicationEngine.Contract.cs rename to src/Neo/SmartContract/ApplicationEngine/ApplicationEngine.Contract.cs diff --git a/src/Neo/SmartContract/ApplicationEngine.Crypto.cs b/src/Neo/SmartContract/ApplicationEngine/ApplicationEngine.Crypto.cs similarity index 100% rename from src/Neo/SmartContract/ApplicationEngine.Crypto.cs rename to src/Neo/SmartContract/ApplicationEngine/ApplicationEngine.Crypto.cs diff --git a/src/Neo/SmartContract/ApplicationEngine.Iterator.cs b/src/Neo/SmartContract/ApplicationEngine/ApplicationEngine.Iterator.cs similarity index 100% rename from src/Neo/SmartContract/ApplicationEngine.Iterator.cs rename to src/Neo/SmartContract/ApplicationEngine/ApplicationEngine.Iterator.cs diff --git a/src/Neo/SmartContract/ApplicationEngine.OpCodePrices.cs b/src/Neo/SmartContract/ApplicationEngine/ApplicationEngine.OpCodePrices.cs similarity index 100% rename from src/Neo/SmartContract/ApplicationEngine.OpCodePrices.cs rename to src/Neo/SmartContract/ApplicationEngine/ApplicationEngine.OpCodePrices.cs diff --git a/src/Neo/SmartContract/ApplicationEngine.Runtime.cs b/src/Neo/SmartContract/ApplicationEngine/ApplicationEngine.Runtime.cs similarity index 99% rename from src/Neo/SmartContract/ApplicationEngine.Runtime.cs rename to src/Neo/SmartContract/ApplicationEngine/ApplicationEngine.Runtime.cs index 3771278839..d06843b806 100644 --- a/src/Neo/SmartContract/ApplicationEngine.Runtime.cs +++ b/src/Neo/SmartContract/ApplicationEngine/ApplicationEngine.Runtime.cs @@ -253,14 +253,14 @@ protected internal bool CheckWitnessInternal(UInt160 hash) if (ScriptContainer is Transaction tx) { Signer[] signers; - OracleResponse response = tx.GetAttribute(); - if (response is null) + OracleResponseAttribute responseAttribute = tx.GetAttribute(); + if (responseAttribute is null) { signers = tx.Signers; } else { - OracleRequest request = NativeContract.Oracle.GetRequest(SnapshotCache, response.Id); + OracleRequest request = NativeContract.Oracle.GetRequest(SnapshotCache, responseAttribute.Id); signers = NativeContract.Ledger.GetTransaction(SnapshotCache, request.OriginalTxid).Signers; } Signer signer = signers.FirstOrDefault(p => p.Account.Equals(hash)); diff --git a/src/Neo/SmartContract/ApplicationEngine.Storage.cs b/src/Neo/SmartContract/ApplicationEngine/ApplicationEngine.Storage.cs similarity index 100% rename from src/Neo/SmartContract/ApplicationEngine.Storage.cs rename to src/Neo/SmartContract/ApplicationEngine/ApplicationEngine.Storage.cs diff --git a/src/Neo/SmartContract/ApplicationEngine.cs b/src/Neo/SmartContract/ApplicationEngine/ApplicationEngine.cs similarity index 100% rename from src/Neo/SmartContract/ApplicationEngine.cs rename to src/Neo/SmartContract/ApplicationEngine/ApplicationEngine.cs diff --git a/src/Neo/SmartContract/ContractBasicMethod.cs b/src/Neo/SmartContract/ContractParameter/ContractBasicMethod.cs similarity index 100% rename from src/Neo/SmartContract/ContractBasicMethod.cs rename to src/Neo/SmartContract/ContractParameter/ContractBasicMethod.cs diff --git a/src/Neo/SmartContract/ContractParameter.cs b/src/Neo/SmartContract/ContractParameter/ContractParameter.cs similarity index 100% rename from src/Neo/SmartContract/ContractParameter.cs rename to src/Neo/SmartContract/ContractParameter/ContractParameter.cs diff --git a/src/Neo/SmartContract/ContractParameterType.cs b/src/Neo/SmartContract/ContractParameter/ContractParameterType.cs similarity index 100% rename from src/Neo/SmartContract/ContractParameterType.cs rename to src/Neo/SmartContract/ContractParameter/ContractParameterType.cs diff --git a/src/Neo/SmartContract/ContractParametersContext.cs b/src/Neo/SmartContract/ContractParameter/ContractParametersContext.cs similarity index 100% rename from src/Neo/SmartContract/ContractParametersContext.cs rename to src/Neo/SmartContract/ContractParameter/ContractParametersContext.cs diff --git a/src/Neo/SmartContract/ContractTask.cs b/src/Neo/SmartContract/ContractTask/ContractTask.cs similarity index 100% rename from src/Neo/SmartContract/ContractTask.cs rename to src/Neo/SmartContract/ContractTask/ContractTask.cs diff --git a/src/Neo/SmartContract/ContractTaskAwaiter.cs b/src/Neo/SmartContract/ContractTask/ContractTaskAwaiter.cs similarity index 100% rename from src/Neo/SmartContract/ContractTaskAwaiter.cs rename to src/Neo/SmartContract/ContractTask/ContractTaskAwaiter.cs diff --git a/src/Neo/SmartContract/ContractTaskMethodBuilder.cs b/src/Neo/SmartContract/ContractTask/ContractTaskMethodBuilder.cs similarity index 100% rename from src/Neo/SmartContract/ContractTaskMethodBuilder.cs rename to src/Neo/SmartContract/ContractTask/ContractTaskMethodBuilder.cs diff --git a/src/Neo/SmartContract/Native/LedgerContract.cs b/src/Neo/SmartContract/Native/LedgerContract.cs index 329e0565d5..9d7e83028c 100644 --- a/src/Neo/SmartContract/Native/LedgerContract.cs +++ b/src/Neo/SmartContract/Native/LedgerContract.cs @@ -52,7 +52,7 @@ internal override ContractTask OnPersistAsync(ApplicationEngine engine) // Store transaction's conflicits. var conflictingSigners = tx.Transaction.Signers.Select(s => s.Account); - foreach (var attr in tx.Transaction.GetAttributes()) + foreach (var attr in tx.Transaction.GetAttributes()) { engine.SnapshotCache.GetAndChange(CreateStorageKey(Prefix_Transaction).Add(attr.Hash), () => new StorageItem(new TransactionState())).FromReplica(new StorageItem(new TransactionState() { BlockIndex = engine.PersistingBlock.Index })); foreach (var signer in conflictingSigners) diff --git a/src/Neo/SmartContract/Native/OracleContract.cs b/src/Neo/SmartContract/Native/OracleContract.cs index be4765581a..f908e93a50 100644 --- a/src/Neo/SmartContract/Native/OracleContract.cs +++ b/src/Neo/SmartContract/Native/OracleContract.cs @@ -76,21 +76,21 @@ 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(); - if (response == null) throw new ArgumentException("Oracle response was not found"); - OracleRequest request = GetRequest(engine.SnapshotCache, response.Id); + OracleResponseAttribute responseAttribute = tx.GetAttribute(); + if (responseAttribute == null) throw new ArgumentException("Oracle response was not found"); + OracleRequest request = GetRequest(engine.SnapshotCache, responseAttribute.Id); if (request == null) throw new ArgumentException("Oracle request was not found"); - engine.SendNotification(Hash, "OracleResponse", new VM.Types.Array(engine.ReferenceCounter) { response.Id, request.OriginalTxid.ToArray() }); + engine.SendNotification(Hash, "OracleResponse", new VM.Types.Array(engine.ReferenceCounter) { responseAttribute.Id, request.OriginalTxid.ToArray() }); StackItem userData = BinarySerializer.Deserialize(request.UserData, engine.Limits, engine.ReferenceCounter); - return engine.CallFromNativeContractAsync(Hash, request.CallbackContract, request.CallbackMethod, request.Url, userData, (int)response.Code, response.Result); + return engine.CallFromNativeContractAsync(Hash, request.CallbackContract, request.CallbackMethod, request.Url, userData, (int)responseAttribute.Code, responseAttribute.Result); } private UInt256 GetOriginalTxid(ApplicationEngine engine) { Transaction tx = (Transaction)engine.ScriptContainer; - OracleResponse response = tx.GetAttribute(); - if (response is null) return tx.Hash; - OracleRequest request = GetRequest(engine.SnapshotCache, response.Id); + OracleResponseAttribute responseAttribute = tx.GetAttribute(); + if (responseAttribute is null) return tx.Hash; + OracleRequest request = GetRequest(engine.SnapshotCache, responseAttribute.Id); return request.OriginalTxid; } @@ -150,11 +150,11 @@ internal override async ContractTask PostPersistAsync(ApplicationEngine engine) foreach (Transaction tx in engine.PersistingBlock.Transactions) { //Filter the response transactions - OracleResponse response = tx.GetAttribute(); - if (response is null) continue; + OracleResponseAttribute responseAttribute = tx.GetAttribute(); + if (responseAttribute is null) continue; //Remove the request from storage - StorageKey key = CreateStorageKey(Prefix_Request).AddBigEndian(response.Id); + StorageKey key = CreateStorageKey(Prefix_Request).AddBigEndian(responseAttribute.Id); OracleRequest request = engine.SnapshotCache.TryGet(key)?.GetInteroperable(); if (request == null) continue; engine.SnapshotCache.Delete(key); @@ -162,14 +162,14 @@ internal override async ContractTask PostPersistAsync(ApplicationEngine engine) //Remove the id from IdList key = CreateStorageKey(Prefix_IdList).Add(GetUrlHash(request.Url)); IdList list = engine.SnapshotCache.GetAndChange(key).GetInteroperable(); - if (!list.Remove(response.Id)) throw new InvalidOperationException(); + if (!list.Remove(responseAttribute.Id)) throw new InvalidOperationException(); if (list.Count == 0) engine.SnapshotCache.Delete(key); //Mint GAS for oracle nodes nodes ??= RoleManagement.GetDesignatedByRole(engine.SnapshotCache, Role.Oracle, engine.PersistingBlock.Index).Select(p => (Contract.CreateSignatureRedeemScript(p).ToScriptHash(), BigInteger.Zero)).ToArray(); if (nodes.Length > 0) { - int index = (int)(response.Id % (ulong)nodes.Length); + int index = (int)(responseAttribute.Id % (ulong)nodes.Length); nodes[index].GAS += GetPrice(engine.SnapshotCache); } } @@ -231,7 +231,7 @@ private async ContractTask Request(ApplicationEngine engine, string url, string private bool Verify(ApplicationEngine engine) { Transaction tx = (Transaction)engine.ScriptContainer; - return tx?.GetAttribute() != null; + return tx?.GetAttribute() != null; } private class IdList : InteroperableList diff --git a/src/Neo/SmartContract/StorageContext.cs b/src/Neo/SmartContract/Storage/StorageContext.cs similarity index 100% rename from src/Neo/SmartContract/StorageContext.cs rename to src/Neo/SmartContract/Storage/StorageContext.cs diff --git a/src/Neo/SmartContract/StorageItem.cs b/src/Neo/SmartContract/Storage/StorageItem.cs similarity index 100% rename from src/Neo/SmartContract/StorageItem.cs rename to src/Neo/SmartContract/Storage/StorageItem.cs diff --git a/src/Neo/SmartContract/StorageKey.cs b/src/Neo/SmartContract/Storage/StorageKey.cs similarity index 100% rename from src/Neo/SmartContract/StorageKey.cs rename to src/Neo/SmartContract/Storage/StorageKey.cs diff --git a/src/Plugins/DBFTPlugin/Consensus/ConsensusService.cs b/src/Plugins/DBFTPlugin/Consensus/ConsensusService.cs index ad1b88feb1..01e3f69f95 100644 --- a/src/Plugins/DBFTPlugin/Consensus/ConsensusService.cs +++ b/src/Plugins/DBFTPlugin/Consensus/ConsensusService.cs @@ -267,7 +267,7 @@ private bool AddTransaction(Transaction tx, bool verify) VerifyResult result; // Firstly, check whether tx has Conlicts attribute with the hash of one of the context's transactions. - foreach (var h in tx.GetAttributes().Select(attr => attr.Hash)) + foreach (var h in tx.GetAttributes().Select(attr => attr.Hash)) { if (context.TransactionHashes.Contains(h)) { @@ -280,7 +280,7 @@ private bool AddTransaction(Transaction tx, bool verify) // After that, check whether context's transactions have Conflicts attribute with tx's hash. foreach (var pooledTx in context.Transactions.Values) { - if (pooledTx.GetAttributes().Select(attr => attr.Hash).Contains(tx.Hash)) + if (pooledTx.GetAttributes().Select(attr => attr.Hash).Contains(tx.Hash)) { result = VerifyResult.HasConflicts; Log($"Rejected tx: {tx.Hash}, {result}{Environment.NewLine}{tx.ToArray().ToHexString()}", LogLevel.Warning); diff --git a/src/Plugins/OracleService/OracleService.cs b/src/Plugins/OracleService/OracleService.cs index fbdee148db..ee4797c729 100644 --- a/src/Plugins/OracleService/OracleService.cs +++ b/src/Plugins/OracleService/OracleService.cs @@ -300,9 +300,9 @@ private async Task ProcessRequestAsync(DataCache snapshot, OracleRequest req) Log($"[{req.OriginalTxid}] Filter '{request.Filter}' error:{ex.Message}"); } } - var response = new OracleResponse() { Id = requestId, Code = code, Result = result }; + var response = new OracleResponseAttribute() { Id = requestId, Code = code, Result = result }; var responseTx = CreateResponseTx(snapshot, request, response, oracleNodes, _system.Settings); - var backupTx = CreateResponseTx(snapshot, request, new OracleResponse() { Code = OracleResponseCode.ConsensusUnreachable, Id = requestId, Result = Array.Empty() }, oracleNodes, _system.Settings, true); + var backupTx = CreateResponseTx(snapshot, request, new OracleResponseAttribute() { Code = OracleResponseCode.ConsensusUnreachable, Id = requestId, Result = Array.Empty() }, oracleNodes, _system.Settings, true); Log($"[{req.OriginalTxid}]-({requestId}) Built response tx[[{responseTx.Hash}]], responseCode:{code}, result:{result.ToHexString()}, validUntilBlock:{responseTx.ValidUntilBlock}, backupTx:{backupTx.Hash}-{backupTx.ValidUntilBlock}"); @@ -377,7 +377,7 @@ private void SyncPendingQueue(DataCache snapshot) } } - public static Transaction CreateResponseTx(DataCache snapshot, OracleRequest request, OracleResponse response, ECPoint[] oracleNodes, ProtocolSettings settings, bool useCurrentHeight = false) + public static Transaction CreateResponseTx(DataCache snapshot, OracleRequest request, OracleResponseAttribute responseAttribute, ECPoint[] oracleNodes, ProtocolSettings settings, bool useCurrentHeight = false) { var requestTx = NativeContract.Ledger.GetTransactionState(snapshot, request.OriginalTxid); var n = oracleNodes.Length; @@ -392,7 +392,7 @@ public static Transaction CreateResponseTx(DataCache snapshot, OracleRequest req var tx = new Transaction() { Version = 0, - Nonce = unchecked((uint)response.Id), + Nonce = unchecked((uint)responseAttribute.Id), ValidUntilBlock = validUntilBlock, Signers = new[] { @@ -407,8 +407,8 @@ public static Transaction CreateResponseTx(DataCache snapshot, OracleRequest req Scopes = WitnessScope.None } }, - Attributes = new[] { response }, - Script = OracleResponse.FixedScript, + Attributes = new[] { responseAttribute }, + Script = OracleResponseAttribute.FixedScript, Witnesses = new Witness[2] }; Dictionary witnessDict = new Dictionary @@ -450,15 +450,15 @@ public static Transaction CreateResponseTx(DataCache snapshot, OracleRequest req + IO.Helper.GetVarSize(size_inv) + size_inv + oracleSignContract.Script.GetVarSize(); var feePerByte = NativeContract.Policy.GetFeePerByte(snapshot); - if (response.Result.Length > OracleResponse.MaxResultSize) + if (responseAttribute.Result.Length > OracleResponseAttribute.MaxResultSize) { - response.Code = OracleResponseCode.ResponseTooLarge; - response.Result = Array.Empty(); + responseAttribute.Code = OracleResponseCode.ResponseTooLarge; + responseAttribute.Result = Array.Empty(); } else if (tx.NetworkFee + (size + tx.Attributes.GetVarSize()) * feePerByte > request.GasForResponse) { - response.Code = OracleResponseCode.InsufficientFunds; - response.Result = Array.Empty(); + responseAttribute.Code = OracleResponseCode.InsufficientFunds; + responseAttribute.Result = Array.Empty(); } size += tx.Attributes.GetVarSize(); tx.NetworkFee += size * feePerByte; diff --git a/src/Plugins/OracleService/Protocols/OracleHttpsProtocol.cs b/src/Plugins/OracleService/Protocols/OracleHttpsProtocol.cs index a825f5e60f..0fde15cec9 100644 --- a/src/Plugins/OracleService/Protocols/OracleHttpsProtocol.cs +++ b/src/Plugins/OracleService/Protocols/OracleHttpsProtocol.cs @@ -84,14 +84,14 @@ public void Dispose() return (OracleResponseCode.Error, message.StatusCode.ToString()); if (!Settings.Default.AllowedContentTypes.Contains(message.Content.Headers.ContentType.MediaType)) return (OracleResponseCode.ContentTypeNotSupported, null); - if (message.Content.Headers.ContentLength.HasValue && message.Content.Headers.ContentLength > OracleResponse.MaxResultSize) + if (message.Content.Headers.ContentLength.HasValue && message.Content.Headers.ContentLength > OracleResponseAttribute.MaxResultSize) return (OracleResponseCode.ResponseTooLarge, null); - byte[] buffer = new byte[OracleResponse.MaxResultSize + 1]; + byte[] buffer = new byte[OracleResponseAttribute.MaxResultSize + 1]; var stream = message.Content.ReadAsStream(cancellation); var read = await stream.ReadAsync(buffer, 0, buffer.Length, cancellation); - if (read > OracleResponse.MaxResultSize) + if (read > OracleResponseAttribute.MaxResultSize) return (OracleResponseCode.ResponseTooLarge, null); var encoding = GetEncoding(message.Content.Headers); diff --git a/src/Plugins/OracleService/Protocols/OracleNeoFSProtocol.cs b/src/Plugins/OracleService/Protocols/OracleNeoFSProtocol.cs index de0cbd8044..f5b986e610 100644 --- a/src/Plugins/OracleService/Protocols/OracleNeoFSProtocol.cs +++ b/src/Plugins/OracleService/Protocols/OracleNeoFSProtocol.cs @@ -99,7 +99,7 @@ private static (OracleResponseCode, string) GetPayload(Client client, Address ad { var objReader = client.GetObjectInit(addr, options: new CallOptions { Ttl = 2 }, context: cancellation); var obj = objReader.ReadHeader(); - if (obj.PayloadSize > OracleResponse.MaxResultSize) + if (obj.PayloadSize > OracleResponseAttribute.MaxResultSize) return (OracleResponseCode.ResponseTooLarge, ""); var payload = new byte[obj.PayloadSize]; int offset = 0; @@ -118,7 +118,7 @@ private static (OracleResponseCode, string) GetPayload(Client client, Address ad { if (ps.Length == 0) throw new FormatException("missing object range (expected 'Offset|Length')"); Range range = ParseRange(ps[0]); - if (range.Length > OracleResponse.MaxResultSize) return (OracleResponseCode.ResponseTooLarge, ""); + if (range.Length > OracleResponseAttribute.MaxResultSize) return (OracleResponseCode.ResponseTooLarge, ""); var res = await client.GetObjectPayloadRangeData(addr, range, options: new CallOptions { Ttl = 2 }, context: cancellation); return (OracleResponseCode.Success, Utility.StrictUTF8.GetString(res)); } diff --git a/src/Plugins/RpcClient/Utility.cs b/src/Plugins/RpcClient/Utility.cs index 37331eec1b..d7260ea279 100644 --- a/src/Plugins/RpcClient/Utility.cs +++ b/src/Plugins/RpcClient/Utility.cs @@ -193,17 +193,17 @@ public static TransactionAttribute TransactionAttributeFromJson(JObject json) return usage switch { TransactionAttributeType.HighPriority => new HighPriorityAttribute(), - TransactionAttributeType.OracleResponse => new OracleResponse() + TransactionAttributeType.OracleResponse => new OracleResponseAttribute() { Id = (ulong)json["id"].AsNumber(), Code = Enum.Parse(json["code"].AsString()), Result = Convert.FromBase64String(json["result"].AsString()), }, - TransactionAttributeType.NotValidBefore => new NotValidBefore() + TransactionAttributeType.NotValidBefore => new NotValidBeforeAttribute() { Height = (uint)json["height"].AsNumber(), }, - TransactionAttributeType.Conflicts => new Conflicts() + TransactionAttributeType.Conflicts => new ConflictsAttribute() { Hash = UInt256.Parse(json["hash"].AsString()) }, diff --git a/src/Plugins/RpcServer/RpcServer.Wallet.cs b/src/Plugins/RpcServer/RpcServer.Wallet.cs index 25a7333aac..84e54331eb 100644 --- a/src/Plugins/RpcServer/RpcServer.Wallet.cs +++ b/src/Plugins/RpcServer/RpcServer.Wallet.cs @@ -439,7 +439,7 @@ protected internal virtual JToken CancelTransaction(JArray _params) var txid = Result.Ok_Or(() => UInt256.Parse(_params[0].AsString()), RpcError.InvalidParams.WithData($"Invalid txid: {_params[0]}")); NativeContract.Ledger.GetTransactionState(system.StoreView, txid).Null_Or(RpcErrorFactory.AlreadyExists("This tx is already confirmed, can't be cancelled.")); - var conflict = new TransactionAttribute[] { new Conflicts() { Hash = txid } }; + var conflict = new TransactionAttribute[] { new ConflictsAttribute() { Hash = txid } }; Signer[] signers = _params.Count >= 2 ? ((JArray)_params[1]).Select(j => new Signer() { Account = AddressToScriptHash(j.AsString(), system.Settings.AddressVersion), Scopes = WitnessScope.None }).ToArray() : Array.Empty(); signers.Any().True_Or(RpcErrorFactory.BadRequest("No signer.")); Transaction tx = new Transaction diff --git a/tests/Neo.Network.RPC.Tests/UT_Utility.cs b/tests/Neo.Network.RPC.Tests/UT_Utility.cs index 3c30069219..1870806bd2 100644 --- a/tests/Neo.Network.RPC.Tests/UT_Utility.cs +++ b/tests/Neo.Network.RPC.Tests/UT_Utility.cs @@ -94,13 +94,13 @@ public void TestGetScriptHash() [TestMethod] public void TestTransactionAttribute() { - var attribute = new Conflicts(); + var attribute = new ConflictsAttribute(); attribute.Hash = UInt256.Zero; var json = attribute.ToJson(); var result = Utility.TransactionAttributeFromJson(json).ToJson(); result.ToString().Should().Be(json.ToString()); - var attribute2 = new OracleResponse(); + var attribute2 = new OracleResponseAttribute(); attribute2.Id = 1234; attribute2.Code = 0; attribute2.Result = new ReadOnlyMemory { }; @@ -108,7 +108,7 @@ public void TestTransactionAttribute() result = Utility.TransactionAttributeFromJson(json).ToJson(); result.ToString().Should().Be(json.ToString()); - var attribute3 = new NotValidBefore(); + var attribute3 = new NotValidBeforeAttribute(); attribute3.Height = 10000; json = attribute3.ToJson(); result = Utility.TransactionAttributeFromJson(json).ToJson(); diff --git a/tests/Neo.Plugins.OracleService.Tests/UT_OracleService.cs b/tests/Neo.Plugins.OracleService.Tests/UT_OracleService.cs index 3276c40c2f..03b7d932c5 100644 --- a/tests/Neo.Plugins.OracleService.Tests/UT_OracleService.cs +++ b/tests/Neo.Plugins.OracleService.Tests/UT_OracleService.cs @@ -90,9 +90,9 @@ public void TestCreateOracleResponseTx() ValidUntilBlock = 1 } })); - OracleResponse response = new OracleResponse() { Id = 1, Code = OracleResponseCode.Success, Result = new byte[] { 0x00 } }; + OracleResponseAttribute responseAttribute = new OracleResponseAttribute() { Id = 1, Code = OracleResponseCode.Success, Result = new byte[] { 0x00 } }; ECPoint[] oracleNodes = new ECPoint[] { ECCurve.Secp256r1.G }; - var tx = OracleService.CreateResponseTx(snapshotCache, request, response, oracleNodes, ProtocolSettings.Default); + var tx = OracleService.CreateResponseTx(snapshotCache, request, responseAttribute, oracleNodes, ProtocolSettings.Default); Assert.AreEqual(166, tx.Size); Assert.AreEqual(2198650, tx.NetworkFee); @@ -101,10 +101,10 @@ public void TestCreateOracleResponseTx() // case (2) The size of attribute exceed the maximum limit request.GasForResponse = 0_10000000; - response.Result = new byte[10250]; - tx = OracleService.CreateResponseTx(snapshotCache, request, response, oracleNodes, ProtocolSettings.Default); + responseAttribute.Result = new byte[10250]; + tx = OracleService.CreateResponseTx(snapshotCache, request, responseAttribute, oracleNodes, ProtocolSettings.Default); Assert.AreEqual(165, tx.Size); - Assert.AreEqual(OracleResponseCode.InsufficientFunds, response.Code); + Assert.AreEqual(OracleResponseCode.InsufficientFunds, responseAttribute.Code); Assert.AreEqual(2197650, tx.NetworkFee); Assert.AreEqual(7802350, tx.SystemFee); } diff --git a/tests/Neo.UnitTests/Ledger/UT_Blockchain.cs b/tests/Neo.UnitTests/Ledger/UT_Blockchain.cs index 9ee5dd6929..dea00687d9 100644 --- a/tests/Neo.UnitTests/Ledger/UT_Blockchain.cs +++ b/tests/Neo.UnitTests/Ledger/UT_Blockchain.cs @@ -121,7 +121,7 @@ public void TestMaliciousOnChainConflict() var tx2 = TestUtils.CreateValidTx(snapshot, walletA, accA.ScriptHash, 1); var tx3 = TestUtils.CreateValidTx(snapshot, walletB, accB.ScriptHash, 2); - tx1.Attributes = new TransactionAttribute[] { new Conflicts() { Hash = tx2.Hash }, new Conflicts() { Hash = tx3.Hash } }; + tx1.Attributes = new TransactionAttribute[] { new ConflictsAttribute() { Hash = tx2.Hash }, new ConflictsAttribute() { Hash = tx3.Hash } }; // Persist tx1. var block = new Block diff --git a/tests/Neo.UnitTests/Ledger/UT_MemoryPool.cs b/tests/Neo.UnitTests/Ledger/UT_MemoryPool.cs index ca4e08341e..632ff63e1e 100644 --- a/tests/Neo.UnitTests/Ledger/UT_MemoryPool.cs +++ b/tests/Neo.UnitTests/Ledger/UT_MemoryPool.cs @@ -269,24 +269,24 @@ public async Task UpdatePoolForBlockPersisted_RemoveBlockConflicts() var mp1 = CreateTransactionWithFeeAndBalanceVerify(txFee); // mp1 doesn't conflict with anyone _unit.TryAdd(mp1, engine.SnapshotCache).Should().Be(VerifyResult.Succeed); var tx1 = CreateTransactionWithFeeAndBalanceVerify(txFee); // but in-block tx1 conflicts with mempooled mp1 => mp1 should be removed from pool after persist - tx1.Attributes = new TransactionAttribute[] { new Conflicts() { Hash = mp1.Hash } }; + tx1.Attributes = new TransactionAttribute[] { new ConflictsAttribute() { Hash = mp1.Hash } }; var mp2 = CreateTransactionWithFeeAndBalanceVerify(txFee); // mp1 and mp2 don't conflict with anyone _unit.TryAdd(mp2, engine.SnapshotCache); var mp3 = CreateTransactionWithFeeAndBalanceVerify(txFee); _unit.TryAdd(mp3, engine.SnapshotCache); var tx2 = CreateTransactionWithFeeAndBalanceVerify(txFee); // in-block tx2 conflicts with mempooled mp2 and mp3 => mp2 and mp3 should be removed from pool after persist - tx2.Attributes = new TransactionAttribute[] { new Conflicts() { Hash = mp2.Hash }, new Conflicts() { Hash = mp3.Hash } }; + tx2.Attributes = new TransactionAttribute[] { new ConflictsAttribute() { Hash = mp2.Hash }, new ConflictsAttribute() { Hash = mp3.Hash } }; var tx3 = CreateTransactionWithFeeAndBalanceVerify(txFee); // in-block tx3 doesn't conflict with anyone var mp4 = CreateTransactionWithFeeAndBalanceVerify(txFee); // mp4 conflicts with in-block tx3 => mp4 should be removed from pool after persist - mp4.Attributes = new TransactionAttribute[] { new Conflicts() { Hash = tx3.Hash } }; + mp4.Attributes = new TransactionAttribute[] { new ConflictsAttribute() { Hash = tx3.Hash } }; _unit.TryAdd(mp4, engine.SnapshotCache); var tx4 = CreateTransactionWithFeeAndBalanceVerify(txFee); // in-block tx4 and tx5 don't conflict with anyone var tx5 = CreateTransactionWithFeeAndBalanceVerify(txFee); var mp5 = CreateTransactionWithFeeAndBalanceVerify(txFee); // mp5 conflicts with in-block tx4 and tx5 => mp5 should be removed from pool after persist - mp5.Attributes = new TransactionAttribute[] { new Conflicts() { Hash = tx4.Hash }, new Conflicts() { Hash = tx5.Hash } }; + mp5.Attributes = new TransactionAttribute[] { new ConflictsAttribute() { Hash = tx4.Hash }, new ConflictsAttribute() { Hash = tx5.Hash } }; _unit.TryAdd(mp5, engine.SnapshotCache); var mp6 = CreateTransactionWithFeeAndBalanceVerify(txFee); // mp6 doesn't conflict with anyone and noone conflicts with mp6 => mp6 should be left in the pool after persist @@ -298,7 +298,7 @@ public async Task UpdatePoolForBlockPersisted_RemoveBlockConflicts() var mp7 = CreateTransactionWithFeeAndBalanceVerify(txFee); // mp7 doesn't conflict with anyone var tx6 = CreateTransactionWithFeeAndBalanceVerify(txFee); // in-block tx6 conflicts with mp7, but doesn't include sender of mp7 into signers list => even if tx6 is included into block, mp7 shouldn't be removed from the pool tx6.Signers = new Signer[] { new Signer() { Account = new UInt160(Crypto.Hash160(new byte[] { 1, 2, 3 })) }, new Signer() { Account = new UInt160(Crypto.Hash160(new byte[] { 4, 5, 6 })) } }; - tx6.Attributes = new TransactionAttribute[] { new Conflicts() { Hash = mp7.Hash } }; + tx6.Attributes = new TransactionAttribute[] { new ConflictsAttribute() { Hash = mp7.Hash } }; _unit.TryAdd(mp7, engine.SnapshotCache); // Act: persist block and reverify all mempooled txs. @@ -337,36 +337,36 @@ public async Task TryAdd_AddRangeOfConflictingTransactions() var mp1 = CreateTransactionWithFeeAndBalanceVerify(txFee); // mp1 doesn't conflict with anyone and not in the pool yet var mp2_1 = CreateTransactionWithFeeAndBalanceVerify(txFee); // mp2_1 conflicts with mp1 and has the same network fee - mp2_1.Attributes = new TransactionAttribute[] { new Conflicts() { Hash = mp1.Hash } }; + mp2_1.Attributes = new TransactionAttribute[] { new ConflictsAttribute() { Hash = mp1.Hash } }; _unit.TryAdd(mp2_1, engine.SnapshotCache); var mp2_2 = CreateTransactionWithFeeAndBalanceVerify(txFee); // mp2_2 also conflicts with mp1 and has the same network fee as mp1 and mp2_1 - mp2_2.Attributes = new TransactionAttribute[] { new Conflicts() { Hash = mp1.Hash } }; + mp2_2.Attributes = new TransactionAttribute[] { new ConflictsAttribute() { Hash = mp1.Hash } }; _unit.TryAdd(mp2_2, engine.SnapshotCache); var mp3 = CreateTransactionWithFeeAndBalanceVerify(2 * txFee); // mp3 conflicts with mp1 and has larger network fee - mp3.Attributes = new TransactionAttribute[] { new Conflicts() { Hash = mp1.Hash } }; + mp3.Attributes = new TransactionAttribute[] { new ConflictsAttribute() { Hash = mp1.Hash } }; _unit.TryAdd(mp3, engine.SnapshotCache); var mp4 = CreateTransactionWithFeeAndBalanceVerify(3 * txFee); // mp4 conflicts with mp3 and has larger network fee - mp4.Attributes = new TransactionAttribute[] { new Conflicts() { Hash = mp3.Hash } }; + mp4.Attributes = new TransactionAttribute[] { new ConflictsAttribute() { Hash = mp3.Hash } }; var malicious = CreateTransactionWithFeeAndBalanceVerify(3 * txFee); // malicious conflicts with mp3 and has larger network fee, but different sender - malicious.Attributes = new TransactionAttribute[] { new Conflicts() { Hash = mp3.Hash } }; + malicious.Attributes = new TransactionAttribute[] { new ConflictsAttribute() { Hash = mp3.Hash } }; malicious.Signers = new Signer[] { new Signer() { Account = new UInt160(Crypto.Hash160(new byte[] { 1, 2, 3 })), Scopes = WitnessScope.None } }; var mp5 = CreateTransactionWithFeeAndBalanceVerify(2 * txFee); // mp5 conflicts with mp4 and has smaller network fee - mp5.Attributes = new TransactionAttribute[] { new Conflicts() { Hash = mp4.Hash } }; + mp5.Attributes = new TransactionAttribute[] { new ConflictsAttribute() { Hash = mp4.Hash } }; var mp6 = CreateTransactionWithFeeAndBalanceVerify(mp2_1.NetworkFee + mp2_2.NetworkFee + 1); // mp6 conflicts with mp2_1 and mp2_2 and has larger network fee. - mp6.Attributes = new TransactionAttribute[] { new Conflicts() { Hash = mp2_1.Hash }, new Conflicts() { Hash = mp2_2.Hash } }; + mp6.Attributes = new TransactionAttribute[] { new ConflictsAttribute() { Hash = mp2_1.Hash }, new ConflictsAttribute() { Hash = mp2_2.Hash } }; var mp7 = CreateTransactionWithFeeAndBalanceVerify(txFee * 2 + 1); // mp7 doesn't conflicts with anyone, but mp8, mp9 and mp10malicious has smaller sum network fee and conflict with mp7. var mp8 = CreateTransactionWithFeeAndBalanceVerify(txFee); - mp8.Attributes = new TransactionAttribute[] { new Conflicts() { Hash = mp7.Hash } }; + mp8.Attributes = new TransactionAttribute[] { new ConflictsAttribute() { Hash = mp7.Hash } }; var mp9 = CreateTransactionWithFeeAndBalanceVerify(txFee); - mp9.Attributes = new TransactionAttribute[] { new Conflicts() { Hash = mp7.Hash } }; + mp9.Attributes = new TransactionAttribute[] { new ConflictsAttribute() { Hash = mp7.Hash } }; var mp10malicious = CreateTransactionWithFeeAndBalanceVerify(txFee); - mp10malicious.Attributes = new TransactionAttribute[] { new Conflicts() { Hash = mp7.Hash } }; + mp10malicious.Attributes = new TransactionAttribute[] { new ConflictsAttribute() { Hash = mp7.Hash } }; mp10malicious.Signers = new Signer[] { new Signer() { Account = maliciousSender, Scopes = WitnessScope.None } }; _unit.SortedTxCount.Should().Be(3); @@ -436,7 +436,7 @@ public async Task TryRemoveVerified_RemoveVerifiedTxWithConflicts() var mp1 = CreateTransactionWithFeeAndBalanceVerify(txFee); // mp1 doesn't conflict with anyone and not in the pool yet var mp2 = CreateTransactionWithFeeAndBalanceVerify(2 * txFee); // mp2 conflicts with mp1 and has larger same network fee - mp2.Attributes = new TransactionAttribute[] { new Conflicts() { Hash = mp1.Hash } }; + mp2.Attributes = new TransactionAttribute[] { new ConflictsAttribute() { Hash = mp1.Hash } }; _unit.TryAdd(mp2, engine.SnapshotCache); _unit.SortedTxCount.Should().Be(1); diff --git a/tests/Neo.UnitTests/Ledger/UT_TransactionVerificationContext.cs b/tests/Neo.UnitTests/Ledger/UT_TransactionVerificationContext.cs index 57cf996acd..1f551012c0 100644 --- a/tests/Neo.UnitTests/Ledger/UT_TransactionVerificationContext.cs +++ b/tests/Neo.UnitTests/Ledger/UT_TransactionVerificationContext.cs @@ -71,13 +71,13 @@ public async Task TestDuplicateOracle() // Test TransactionVerificationContext verificationContext = new(); var tx = CreateTransactionWithFee(1, 2); - tx.Attributes = new TransactionAttribute[] { new OracleResponse() { Code = OracleResponseCode.ConsensusUnreachable, Id = 1, Result = Array.Empty() } }; + tx.Attributes = new TransactionAttribute[] { new OracleResponseAttribute() { Code = OracleResponseCode.ConsensusUnreachable, Id = 1, Result = Array.Empty() } }; var conflicts = new List(); verificationContext.CheckTransaction(tx, conflicts, snapshotCache).Should().BeTrue(); verificationContext.AddTransaction(tx); tx = CreateTransactionWithFee(2, 1); - tx.Attributes = new TransactionAttribute[] { new OracleResponse() { Code = OracleResponseCode.ConsensusUnreachable, Id = 1, Result = Array.Empty() } }; + tx.Attributes = new TransactionAttribute[] { new OracleResponseAttribute() { Code = OracleResponseCode.ConsensusUnreachable, Id = 1, Result = Array.Empty() } }; verificationContext.CheckTransaction(tx, conflicts, snapshotCache).Should().BeFalse(); } diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Conflicts.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Conflicts.cs index a0dac53fbe..399aa1d2ba 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Conflicts.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Conflicts.cs @@ -34,14 +34,14 @@ public class UT_Conflicts [TestMethod] public void Size_Get() { - var test = new Conflicts() { Hash = _u }; + var test = new ConflictsAttribute() { Hash = _u }; test.Size.Should().Be(1 + 32); } [TestMethod] public void ToJson() { - var test = new Conflicts() { Hash = _u }; + var test = new ConflictsAttribute() { Hash = _u }; var json = test.ToJson().ToString(); Assert.AreEqual(@"{""type"":""Conflicts"",""hash"":""0x0101010101010101010101010101010101010101010101010101010101010101""}", json); } @@ -49,15 +49,15 @@ public void ToJson() [TestMethod] public void DeserializeAndSerialize() { - var test = new Conflicts() { Hash = _u }; + var test = new ConflictsAttribute() { Hash = _u }; - var clone = test.ToArray().AsSerializable(); + var clone = test.ToArray().AsSerializable(); Assert.AreEqual(clone.Type, test.Type); // As transactionAttribute byte[] buffer = test.ToArray(); var reader = new MemoryReader(buffer); - clone = TransactionAttribute.DeserializeFrom(ref reader) as Conflicts; + clone = TransactionAttribute.DeserializeFrom(ref reader) as ConflictsAttribute; Assert.AreEqual(clone.Type, test.Type); // Wrong type @@ -72,7 +72,7 @@ public void DeserializeAndSerialize() [TestMethod] public void Verify() { - var test = new Conflicts() { Hash = _u }; + var test = new ConflictsAttribute() { Hash = _u }; var snapshotCache = TestBlockchain.GetTestSnapshotCache(); var key = Ledger.UT_MemoryPool.CreateStorageKey(NativeContract.Ledger.Id, Prefix_Transaction, _u.ToArray()); diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_NotValidBefore.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_NotValidBefore.cs index bff21a4e5e..8be263863b 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_NotValidBefore.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_NotValidBefore.cs @@ -24,14 +24,14 @@ public class UT_NotValidBefore [TestMethod] public void Size_Get() { - var test = new NotValidBefore(); + var test = new NotValidBeforeAttribute(); test.Size.Should().Be(5); } [TestMethod] public void ToJson() { - var test = new NotValidBefore + var test = new NotValidBeforeAttribute { Height = 42 }; @@ -42,16 +42,16 @@ public void ToJson() [TestMethod] public void DeserializeAndSerialize() { - var test = new NotValidBefore(); + var test = new NotValidBeforeAttribute(); - var clone = test.ToArray().AsSerializable(); + var clone = test.ToArray().AsSerializable(); Assert.AreEqual(clone.Type, test.Type); // As transactionAttribute byte[] buffer = test.ToArray(); var reader = new MemoryReader(buffer); - clone = TransactionAttribute.DeserializeFrom(ref reader) as NotValidBefore; + clone = TransactionAttribute.DeserializeFrom(ref reader) as NotValidBeforeAttribute; Assert.AreEqual(clone.Type, test.Type); // Wrong type @@ -67,7 +67,7 @@ public void DeserializeAndSerialize() reader = new MemoryReader(buffer); try { - new NotValidBefore().Deserialize(ref reader); + new NotValidBeforeAttribute().Deserialize(ref reader); Assert.Fail(); } catch (FormatException) { } @@ -76,7 +76,7 @@ public void DeserializeAndSerialize() [TestMethod] public void Verify() { - var test = new NotValidBefore(); + var test = new NotValidBeforeAttribute(); var snapshotCache = TestBlockchain.GetTestSnapshotCache(); test.Height = NativeContract.Ledger.CurrentIndex(snapshotCache) + 1; diff --git a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs index dc910c5142..76f4c2a902 100644 --- a/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs +++ b/tests/Neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs @@ -1104,12 +1104,12 @@ public void Test_GetAttribute() Witnesses = [], }; - Assert.IsNull(tx.GetAttribute()); + Assert.IsNull(tx.GetAttribute()); Assert.IsNull(tx.GetAttribute()); tx.Attributes = [new HighPriorityAttribute()]; - Assert.IsNull(tx.GetAttribute()); + Assert.IsNull(tx.GetAttribute()); Assert.IsNotNull(tx.GetAttribute()); } diff --git a/tests/Neo.UnitTests/TestUtils.Transaction.cs b/tests/Neo.UnitTests/TestUtils.Transaction.cs index 12e9b4ec0e..40e94475aa 100644 --- a/tests/Neo.UnitTests/TestUtils.Transaction.cs +++ b/tests/Neo.UnitTests/TestUtils.Transaction.cs @@ -69,7 +69,7 @@ public static Transaction CreateValidTx(DataCache snapshot, NEP6Wallet wallet, U } ], account); - tx.Attributes = conflicts.Select(conflict => new Conflicts { Hash = conflict }).ToArray(); + tx.Attributes = conflicts.Select(conflict => new ConflictsAttribute { Hash = conflict }).ToArray(); tx.Nonce = nonce; tx.Signers = [new Signer { Account = account, Scopes = WitnessScope.CalledByEntry }]; var data = new ContractParametersContext(snapshot, tx, TestProtocolSettings.Default.Network); @@ -169,7 +169,7 @@ public static Transaction CreateInvalidTransaction(DataCache snapshot, NEP6Walle case InvalidTransactionType.Conflicting: // To create a conflicting transaction, we'd need another valid transaction. // For simplicity, we'll just add a Conflicts attribute with a random hash. - tx.Attributes = [new Conflicts { Hash = conflict }]; + tx.Attributes = [new ConflictsAttribute { Hash = conflict }]; break; }