From eded6bdffaaeb80da1ea467c6fb04879818c70fb Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Tue, 11 Jun 2024 09:37:07 +0300 Subject: [PATCH] P2P: move NotaryAssisted transaction attribute under D hardfork Signed-off-by: Anna Shaleva --- src/Neo/Network/P2P/Payloads/Transaction.cs | 8 +- .../SmartContract/Native/PolicyContract.cs | 77 +++++++++++++++++-- 2 files changed, 76 insertions(+), 9 deletions(-) diff --git a/src/Neo/Network/P2P/Payloads/Transaction.cs b/src/Neo/Network/P2P/Payloads/Transaction.cs index b922674d910..16d44517412 100644 --- a/src/Neo/Network/P2P/Payloads/Transaction.cs +++ b/src/Neo/Network/P2P/Payloads/Transaction.cs @@ -370,13 +370,15 @@ public virtual VerifyResult VerifyStateDependent(ProtocolSettings settings, Data if (!(context?.CheckTransaction(this, conflictsList, snapshot) ?? true)) return VerifyResult.InsufficientFunds; long attributesFee = 0; foreach (TransactionAttribute attribute in Attributes) + { if (!attribute.Verify(snapshot, this)) return VerifyResult.InvalidAttribute; - else - attributesFee += attribute.CalculateNetworkFee(snapshot, this); + if (attribute.Type == TransactionAttributeType.NotaryAssisted && !settings.IsHardforkEnabled(Hardfork.HF_Domovoi, height)) + return VerifyResult.InvalidAttribute; + attributesFee += attribute.CalculateNetworkFee(snapshot, this); + } long netFeeDatoshi = NetworkFee - (Size * NativeContract.Policy.GetFeePerByte(snapshot)) - attributesFee; if (netFeeDatoshi < 0) return VerifyResult.InsufficientFunds; - if (netFeeDatoshi > MaxVerificationGas) netFeeDatoshi = MaxVerificationGas; uint execFeeFactor = NativeContract.Policy.GetExecFeeFactor(snapshot); for (int i = 0; i < hashes.Length; i++) diff --git a/src/Neo/SmartContract/Native/PolicyContract.cs b/src/Neo/SmartContract/Native/PolicyContract.cs index adeb2f1c19e..bac8deef49f 100644 --- a/src/Neo/SmartContract/Native/PolicyContract.cs +++ b/src/Neo/SmartContract/Native/PolicyContract.cs @@ -79,6 +79,9 @@ internal override ContractTask InitializeAsync(ApplicationEngine engine, Hardfor engine.Snapshot.Add(CreateStorageKey(Prefix_FeePerByte), new StorageItem(DefaultFeePerByte)); engine.Snapshot.Add(CreateStorageKey(Prefix_ExecFeeFactor), new StorageItem(DefaultExecFeeFactor)); engine.Snapshot.Add(CreateStorageKey(Prefix_StoragePrice), new StorageItem(DefaultStoragePrice)); + } + if (hardfork == Hardfork.HF_Domovoi) + { engine.Snapshot.Add(CreateStorageKey(Prefix_AttributeFee).Add((byte)TransactionAttributeType.NotaryAssisted), new StorageItem(DefaultNotaryAssistedAttributeFee)); } return ContractTask.CompletedTask; @@ -118,21 +121,48 @@ public uint GetStoragePrice(DataCache snapshot) } /// - /// Gets the fee for attribute. + /// Gets the fee for attribute before Domovoi hardfork. + /// + /// The snapshot used to read data. + /// Attribute type excluding + /// The fee for attribute. + [ContractMethod(Hardfork.HF_Domovoi, CpuFee = 1 << 15, RequiredCallFlags = CallFlags.ReadStates, Name = "getAttributeFee")] + public uint GetAttributeFeeV0(DataCache snapshot, byte attributeType) + { + return GetAttributeFee(snapshot, attributeType, false); + } + + /// + /// Gets the fee for attribute after Domovoi hardfork. /// /// The snapshot used to read data. /// Attribute type /// The fee for attribute. - [ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.ReadStates)] + [ContractMethod(true, Hardfork.HF_Domovoi, CpuFee = 1 << 15, RequiredCallFlags = CallFlags.ReadStates)] public uint GetAttributeFee(DataCache snapshot, byte attributeType) { - if (!Enum.IsDefined(typeof(TransactionAttributeType), attributeType)) throw new InvalidOperationException(); + return GetAttributeFee(snapshot, attributeType, true); + } + + /// + /// Generic handler for GetAttributeFeeV0 and GetAttributeFeeV1 that + /// gets the fee for attribute. + /// + /// The snapshot used to read data. + /// Attribute type + /// Whether to support attribute type. + /// The fee for attribute. + private uint GetAttributeFee(DataCache snapshot, byte attributeType, bool allowNotaryAssisted) + { + if (!Enum.IsDefined(typeof(TransactionAttributeType), attributeType) || (!allowNotaryAssisted && attributeType == (byte)(TransactionAttributeType.NotaryAssisted))) + throw new InvalidOperationException(); StorageItem entry = snapshot.TryGet(CreateStorageKey(Prefix_AttributeFee).Add(attributeType)); if (entry == null) return DefaultAttributeFee; return (uint)(BigInteger)entry; } + /// /// Determines whether the specified account is blocked. /// @@ -145,10 +175,45 @@ public bool IsBlocked(DataCache snapshot, UInt160 account) return snapshot.Contains(CreateStorageKey(Prefix_BlockedAccount).Add(account)); } - [ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.States)] - private void SetAttributeFee(ApplicationEngine engine, byte attributeType, uint value) + /// + /// Sets the fee for attribute before Domovoi hardfork. + /// + /// The engine used to check committee witness and read data. + /// Attribute type excluding + /// Attribute fee value + /// The fee for attribute. + [ContractMethod(Hardfork.HF_Domovoi, CpuFee = 1 << 15, RequiredCallFlags = CallFlags.States, Name = "setAttributeFee")] + private void SetAttributeFeeV0(ApplicationEngine engine, byte attributeType, uint value) + { + SetAttributeFee(engine, attributeType, value, false); + } + + /// + /// Sets the fee for attribute after Domovoi hardfork. + /// + /// The engine used to check committee witness and read data. + /// Attribute type excluding + /// Attribute fee value + /// The fee for attribute. + [ContractMethod(true, Hardfork.HF_Domovoi, CpuFee = 1 << 15, RequiredCallFlags = CallFlags.States, Name = "setAttributeFee")] + private void SetAttributeFeeV1(ApplicationEngine engine, byte attributeType, uint value) + { + SetAttributeFee(engine, attributeType, value, true); + } + + /// + /// Generic handler for SetAttributeFeeV0 and SetAttributeFeeV1 that + /// gets the fee for attribute. + /// + /// The engine used to check committee witness and read data. + /// Attribute type + /// Attribute fee value + /// Whether to support attribute type. + /// The fee for attribute. + private void SetAttributeFee(ApplicationEngine engine, byte attributeType, uint value, bool allowNotaryAssisted) { - if (!Enum.IsDefined(typeof(TransactionAttributeType), attributeType)) throw new InvalidOperationException(); + if (!Enum.IsDefined(typeof(TransactionAttributeType), attributeType) || (!allowNotaryAssisted && attributeType == (byte)(TransactionAttributeType.NotaryAssisted))) + throw new InvalidOperationException(); if (value > MaxAttributeFee) throw new ArgumentOutOfRangeException(nameof(value)); if (!CheckCommittee(engine)) throw new InvalidOperationException();