From 0ce4311376754b4cea7fc41dd3a6ae0d8077dd0b Mon Sep 17 00:00:00 2001 From: Owen Zhang <38493437+superboyiii@users.noreply.github.com> Date: Thu, 21 Mar 2019 16:32:41 +0800 Subject: [PATCH] Make calculation for extra gas on "send*" RPC (#70) * Make calculation for extra gas on "send*" RPC * Fix for the calculation when little overstep --- RpcWallet/RpcWallet.cs | 46 ++++++++++++++++++++++++++++++++- RpcWallet/RpcWallet.csproj | 11 ++++++++ RpcWallet/RpcWallet/config.json | 5 ++++ RpcWallet/Settings.cs | 29 +++++++++++++++++++++ 4 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 RpcWallet/RpcWallet/config.json create mode 100644 RpcWallet/Settings.cs diff --git a/RpcWallet/RpcWallet.cs b/RpcWallet/RpcWallet.cs index 6c33f92b1..08365cea0 100644 --- a/RpcWallet/RpcWallet.cs +++ b/RpcWallet/RpcWallet.cs @@ -1,4 +1,4 @@ -using Akka.Actor; +using Akka.Actor; using Microsoft.AspNetCore.Http; using Neo.IO; using Neo.IO.Json; @@ -21,6 +21,7 @@ public class RpcWallet : Plugin, IRpcPlugin public override void Configure() { + Settings.Load(GetConfiguration()); } public void PreProcess(HttpContext context, string method, JArray _params) @@ -307,8 +308,25 @@ private JObject SendFrom(UIntBase assetId, UInt160 from, UInt160 to, string valu ScriptHash = to } }, from: from, change_address: change_address, fee: fee); + if (tx.Size > 1024) + { + fee += Fixed8.FromDecimal(tx.Size * 0.00001m + 0.001m); + tx = Wallet.MakeTransaction(null, new[] + { + new TransferOutput + { + AssetId = assetId, + Value = amount, + ScriptHash = to + } + }, from: from, change_address: change_address, fee: fee); + } if (tx == null) throw new RpcException(-300, "Insufficient funds"); + if (fee > Settings.Default.MaxFee) + { + throw new RpcException(-100, "The necessary fee is more than the Max_fee, this transaction is failed. Please increase your Max_fee value."); + } return SignAndRelay(tx); } @@ -334,8 +352,17 @@ private JObject SendMany(UInt160 from, JArray to, Fixed8 fee, UInt160 change_add if (fee < Fixed8.Zero) throw new RpcException(-32602, "Invalid params"); Transaction tx = Wallet.MakeTransaction(null, outputs, from: from, change_address: change_address, fee: fee); + if (tx.Size > 1024) + { + fee += Fixed8.FromDecimal(tx.Size * 0.00001m + 0.001m); + tx = Wallet.MakeTransaction(null, outputs, from: from, change_address: change_address, fee: fee); + } if (tx == null) throw new RpcException(-300, "Insufficient funds"); + if (fee > Settings.Default.MaxFee) + { + throw new RpcException(-100, "The necessary fee is more than the Max_fee, this transaction is failed. Please increase your Max_fee value."); + } return SignAndRelay(tx); } @@ -357,8 +384,25 @@ private JObject SendToAddress(UIntBase assetId, UInt160 scriptHash, string value ScriptHash = scriptHash } }, change_address: change_address, fee: fee); + if (tx.Size > 1024) + { + fee += Fixed8.FromDecimal(tx.Size * 0.00001m + 0.001m); + tx = Wallet.MakeTransaction(null, new[] + { + new TransferOutput + { + AssetId = assetId, + Value = amount, + ScriptHash = scriptHash + } + }, change_address: change_address, fee: fee); + } if (tx == null) throw new RpcException(-300, "Insufficient funds"); + if (fee > Settings.Default.MaxFee) + { + throw new RpcException(-100, "The necessary fee is more than the Max_fee, this transaction is failed. Please increase your Max_fee value."); + } return SignAndRelay(tx); } } diff --git a/RpcWallet/RpcWallet.csproj b/RpcWallet/RpcWallet.csproj index a88f11518..a19ce802b 100644 --- a/RpcWallet/RpcWallet.csproj +++ b/RpcWallet/RpcWallet.csproj @@ -5,9 +5,20 @@ netstandard2.0 Neo.Plugins + + + + PreserveNewest + PreserveNewest + + + + + + diff --git a/RpcWallet/RpcWallet/config.json b/RpcWallet/RpcWallet/config.json new file mode 100644 index 000000000..752d78ff9 --- /dev/null +++ b/RpcWallet/RpcWallet/config.json @@ -0,0 +1,5 @@ +{ + "PluginConfiguration": { + "MaxFee": 0.1 + } +} diff --git a/RpcWallet/Settings.cs b/RpcWallet/Settings.cs new file mode 100644 index 000000000..ad7ebe412 --- /dev/null +++ b/RpcWallet/Settings.cs @@ -0,0 +1,29 @@ +using Microsoft.Extensions.Configuration; +using System; +using System.Linq; + +namespace Neo.Plugins +{ + internal class Settings + { + public Fixed8 MaxFee { get; } + + public static Settings Default { get; private set; } + + private Settings(IConfigurationSection section) + { + this.MaxFee = GetValueOrDefault(section.GetSection("MaxFee"), Fixed8.FromDecimal(0.1M), p => Fixed8.Parse(p)); + } + + public T GetValueOrDefault(IConfigurationSection section, T defaultValue, Func selector) + { + if (section.Value == null) return defaultValue; + return selector(section.Value); + } + + public static void Load(IConfigurationSection section) + { + Default = new Settings(section); + } + } +}