From e7d3e0a94dc03662f40e4150a92e1a396510847c Mon Sep 17 00:00:00 2001 From: Krain Chen Date: Wed, 8 Jan 2020 14:44:55 +0800 Subject: [PATCH 1/4] change network fee calculation --- src/RpcClient/TransactionManager.cs | 60 +++++++------------ .../UT_TransactionManager.cs | 2 +- 2 files changed, 24 insertions(+), 38 deletions(-) diff --git a/src/RpcClient/TransactionManager.cs b/src/RpcClient/TransactionManager.cs index d9992ab4c..0dd4bb143 100644 --- a/src/RpcClient/TransactionManager.cs +++ b/src/RpcClient/TransactionManager.cs @@ -4,9 +4,9 @@ using Neo.Network.RPC.Models; using Neo.SmartContract; using Neo.SmartContract.Native; -using Neo.VM; using Neo.Wallets; using System; +using System.Linq; namespace Neo.Network.RPC { @@ -84,7 +84,7 @@ public TransactionManager MakeTransaction(byte[] script, TransactionAttribute[] context = new ContractParametersContext(Tx); // set networkfee to estimate value when networkFee is 0 - Tx.NetworkFee = networkFee == 0 ? EstimateNetworkFee() : networkFee; + Tx.NetworkFee = networkFee == 0 ? CalculateNetworkFee(true) : networkFee; var gasBalance = nep5API.BalanceOf(NativeContract.GAS.Hash, sender); if (gasBalance >= Tx.SystemFee + Tx.NetworkFee) return this; @@ -92,53 +92,39 @@ public TransactionManager MakeTransaction(byte[] script, TransactionAttribute[] } /// - /// Estimate NetworkFee, assuming the witnesses are basic Signature Contract + /// Calculate NetworkFee /// - private long EstimateNetworkFee() + /// assuming the witnesses are basic Signature Contract if set to true + /// + private long CalculateNetworkFee(bool isEstimate = false) { long networkFee = 0; UInt160[] hashes = Tx.GetScriptHashesForVerifying(null); int size = Transaction.HeaderSize + Tx.Attributes.GetVarSize() + Tx.Script.GetVarSize() + IO.Helper.GetVarSize(hashes.Length); - - // assume the hashes are single Signature - foreach (var hash in hashes) + foreach (UInt160 hash in hashes) { - size += 166; - networkFee += ApplicationEngine.OpCodePrices[OpCode.PUSHNULL]; // message - using (ScriptBuilder sb = new ScriptBuilder()) + byte[] witness_script = null; + if (isEstimate) { - networkFee += ApplicationEngine.OpCodePrices[(OpCode)sb.EmitPush(64).ToArray()[0]]; // signature - networkFee += ApplicationEngine.OpCodePrices[(OpCode)sb.EmitPush(33).ToArray()[0]]; // pubKey - size += sb.ToArray().Length; + // assuming the witnesses are basic Signature Contract + KeyPair one = new KeyPair(new byte[31].Concat(new byte[] { 1 }).ToArray()); + witness_script = Contract.CreateSignatureRedeemScript(one.PublicKey); } - networkFee += InteropService.GetPrice(InteropService.Crypto.ECDsaVerify, null); - } - - networkFee += size * policyAPI.GetFeePerByte(); - return networkFee; - } - - /// - /// Calculate NetworkFee with context items - /// - private long CalculateNetworkFee() - { - long networkFee = 0; - UInt160[] hashes = Tx.GetScriptHashesForVerifying(null); - int size = Transaction.HeaderSize + Tx.Attributes.GetVarSize() + Tx.Script.GetVarSize() + IO.Helper.GetVarSize(hashes.Length); - foreach (UInt160 hash in hashes) - { - byte[] witness_script = context.GetScript(hash); - if (witness_script is null || witness_script.Length == 0) + else { - try + // calculate NetworkFee with context items + witness_script = context.GetScript(hash); + if (witness_script is null || witness_script.Length == 0) { - witness_script = rpcClient.GetContractState(hash.ToString())?.Script; + try + { + witness_script = rpcClient.GetContractState(hash.ToString())?.Script; + } + catch { } } - catch { } - } - if (witness_script is null) continue; + if (witness_script is null) continue; + } networkFee += Wallet.CalculateNetWorkFee(witness_script, ref size); } diff --git a/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs b/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs index 45814d259..2e4a779ec 100644 --- a/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs +++ b/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs @@ -119,7 +119,7 @@ public void TestSign() // get signature from Witnesses var tx = txManager.Tx; - byte[] signature = tx.Witnesses[0].InvocationScript.Skip(1).ToArray(); + byte[] signature = tx.Witnesses[0].InvocationScript.Skip(2).ToArray(); Assert.IsTrue(Crypto.VerifySignature(tx.GetHashData(), signature, keyPair1.PublicKey.EncodePoint(false).Skip(1).ToArray())); From 24b10605f68b2f69d6204e8bfd34faf99fcb0512 Mon Sep 17 00:00:00 2001 From: Krain Chen Date: Wed, 8 Jan 2020 15:34:20 +0800 Subject: [PATCH 2/4] update to CI00847 --- src/RpcClient/RpcClient.csproj | 4 ++-- src/RpcClient/TransactionManager.cs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/RpcClient/RpcClient.csproj b/src/RpcClient/RpcClient.csproj index d2e2e89dc..2f4aed74b 100644 --- a/src/RpcClient/RpcClient.csproj +++ b/src/RpcClient/RpcClient.csproj @@ -1,7 +1,7 @@ - 3.0.0-CI00825 + 3.0.0-CI00847 netstandard2.1 Neo.Network.RPC The Neo Project @@ -14,7 +14,7 @@ - + diff --git a/src/RpcClient/TransactionManager.cs b/src/RpcClient/TransactionManager.cs index 0dd4bb143..9592c4ba1 100644 --- a/src/RpcClient/TransactionManager.cs +++ b/src/RpcClient/TransactionManager.cs @@ -62,9 +62,9 @@ public TransactionManager MakeTransaction(byte[] script, TransactionAttribute[] Script = script, Sender = sender, ValidUntilBlock = height + Transaction.MaxValidUntilBlockIncrement, - Attributes = attributes ?? new TransactionAttribute[0], - Cosigners = cosigners ?? new Cosigner[0], - Witnesses = new Witness[0] + Attributes = attributes ?? Array.Empty(), + Cosigners = cosigners ?? Array.Empty(), + Witnesses = Array.Empty() }; // Add witness hashes parameter to pass CheckWitness @@ -126,7 +126,7 @@ private long CalculateNetworkFee(bool isEstimate = false) if (witness_script is null) continue; } - networkFee += Wallet.CalculateNetWorkFee(witness_script, ref size); + networkFee += Wallet.CalculateNetworkFee(witness_script, ref size); } networkFee += size * policyAPI.GetFeePerByte(); return networkFee; From b3d1d3012197ff7b5670ad8083c6c5ac48d153ce Mon Sep 17 00:00:00 2001 From: Krain Chen Date: Wed, 8 Jan 2020 19:12:32 +0800 Subject: [PATCH 3/4] fix fee issue --- src/RpcClient/TransactionManager.cs | 2 +- tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/RpcClient/TransactionManager.cs b/src/RpcClient/TransactionManager.cs index 9592c4ba1..2f8c27571 100644 --- a/src/RpcClient/TransactionManager.cs +++ b/src/RpcClient/TransactionManager.cs @@ -100,7 +100,7 @@ private long CalculateNetworkFee(bool isEstimate = false) { long networkFee = 0; UInt160[] hashes = Tx.GetScriptHashesForVerifying(null); - int size = Transaction.HeaderSize + Tx.Attributes.GetVarSize() + Tx.Script.GetVarSize() + IO.Helper.GetVarSize(hashes.Length); + int size = Transaction.HeaderSize + Tx.Attributes.GetVarSize() + Tx.Cosigners.GetVarSize() + Tx.Script.GetVarSize() + IO.Helper.GetVarSize(hashes.Length); foreach (UInt160 hash in hashes) { byte[] witness_script = null; diff --git a/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs b/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs index 2e4a779ec..a78db5c3e 100644 --- a/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs +++ b/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs @@ -112,8 +112,15 @@ public void TestSign() } }; + Cosigner[] cosigners = new Cosigner[1] { + new Cosigner{ + Account = sender, + Scopes = WitnessScope.Global + } + }; + byte[] script = new byte[1]; - txManager.MakeTransaction(script, attributes) + txManager.MakeTransaction(script, attributes, cosigners) .AddSignature(keyPair1) .Sign(); @@ -122,6 +129,7 @@ public void TestSign() byte[] signature = tx.Witnesses[0].InvocationScript.Skip(2).ToArray(); Assert.IsTrue(Crypto.VerifySignature(tx.GetHashData(), signature, keyPair1.PublicKey.EncodePoint(false).Skip(1).ToArray())); + Assert.AreEqual(1191390, tx.NetworkFee); // duplicate sign should not add new witness txManager.AddSignature(keyPair1).Sign(); From aec70b023321ba7bf7034ce982c5ebd416145342 Mon Sep 17 00:00:00 2001 From: Krain Chen Date: Thu, 9 Jan 2020 10:17:10 +0800 Subject: [PATCH 4/4] add UT for network fee --- tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs b/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs index a78db5c3e..56925ff58 100644 --- a/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs +++ b/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs @@ -129,7 +129,9 @@ public void TestSign() byte[] signature = tx.Witnesses[0].InvocationScript.Skip(2).ToArray(); Assert.IsTrue(Crypto.VerifySignature(tx.GetHashData(), signature, keyPair1.PublicKey.EncodePoint(false).Skip(1).ToArray())); - Assert.AreEqual(1191390, tx.NetworkFee); + // verify network fee + long networkFee = tx.Size * (long)1000 + ApplicationEngine.OpCodePrices[OpCode.PUSHDATA1] + ApplicationEngine.OpCodePrices[OpCode.PUSHDATA1] + ApplicationEngine.OpCodePrices[OpCode.PUSHNULL] + InteropService.GetPrice(InteropService.Crypto.ECDsaVerify, null); + Assert.AreEqual(networkFee, tx.NetworkFee); // duplicate sign should not add new witness txManager.AddSignature(keyPair1).Sign();