-
-
Save janus/9ffb247463eeba62e1d007949f3ddb2d to your computer and use it in GitHub Desktop.
Error and Exception
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/GWallet.Backend.Tests/GWallet.Backend.Tests.fsproj b/src/GWallet.Backend.Tests/GWallet.Backend.Tests.fsproj | |
index c095a47..8317fd1 100644 | |
--- a/src/GWallet.Backend.Tests/GWallet.Backend.Tests.fsproj | |
+++ b/src/GWallet.Backend.Tests/GWallet.Backend.Tests.fsproj | |
@@ -72,6 +72,7 @@ | |
<Reference Include="mscorlib" /> | |
<Reference Include="nunit.framework"> | |
<HintPath>..\..\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath> | |
+ <Package>nunit</Package> | |
</Reference> | |
<Reference Include="System" /> | |
<Reference Include="System.Core" /> | |
diff --git a/src/GWallet.Backend/Account.fs b/src/GWallet.Backend/Account.fs | |
index 84e618b..ec303d3 100644 | |
--- a/src/GWallet.Backend/Account.fs | |
+++ b/src/GWallet.Backend/Account.fs | |
@@ -139,15 +139,15 @@ module Account = | |
} | |
// TODO: add tests for these (just in case address validation breaks after upgrading our dependencies) | |
- let ValidateAddress (currency: Currency) (address: string): Async<unit> = async { | |
+ let ValidateAddress (currency: Currency) (address: string) = | |
if currency.IsEtherBased() then | |
Ether.Account.ValidateAddress currency address | |
- do! Ether.Server.CheckIfAddressIsAValidPaymentDestination currency address | |
+ | |
elif currency.IsUtxo() then | |
UtxoCoin.Account.ValidateAddress currency address | |
else | |
failwith (sprintf "Unknown currency %A" currency) | |
- } | |
+ | |
let EstimateFee (account: IAccount) (amount: TransferAmount) destination: Async<IBlockchainFeeInfo> = | |
@@ -312,9 +312,9 @@ module Account = | |
raise DestinationEqualToOrigin | |
let currency = baseAccount.Currency | |
+ ValidateAddress currency destination | |
async { | |
- do! ValidateAddress currency destination | |
let! txId = | |
match txMetadata with | |
@@ -393,9 +393,9 @@ module Account = | |
File.WriteAllText(filePath, json) | |
- let CreateReadOnlyAccounts (watchWalletInfo: WatchWalletInfo): Async<unit> = async { | |
+ let CreateReadOnlyAccounts (watchWalletInfo: WatchWalletInfo) = | |
for etherCurrency in Currency.GetAll().Where(fun currency -> currency.IsEtherBased()) do | |
- do! ValidateAddress etherCurrency watchWalletInfo.EtherPublicAddress | |
+ ValidateAddress etherCurrency watchWalletInfo.EtherPublicAddress | |
let conceptAccountForReadOnlyAccount = { | |
Currency = etherCurrency | |
FileRepresentation = { Name = watchWalletInfo.EtherPublicAddress; Content = fun _ -> String.Empty } | |
@@ -407,14 +407,14 @@ module Account = | |
let address = | |
UtxoCoin.Account.GetPublicAddressFromPublicKey utxoCurrency | |
(NBitcoin.PubKey(watchWalletInfo.UtxoCoinPublicKey)) | |
- do! ValidateAddress utxoCurrency address | |
+ ValidateAddress utxoCurrency address | |
let conceptAccountForReadOnlyAccount = { | |
Currency = utxoCurrency | |
FileRepresentation = { Name = address; Content = fun _ -> watchWalletInfo.UtxoCoinPublicKey } | |
ExtractPublicAddressFromConfigFileFunc = (fun file -> file.Name) | |
} | |
Config.AddAccount conceptAccountForReadOnlyAccount AccountKind.ReadOnly |> ignore | |
- } | |
+ | |
let Remove (account: ReadOnlyAccount) = | |
Config.RemoveReadOnlyAccount account | |
diff --git a/src/GWallet.Backend/Ether/EtherAccount.fs b/src/GWallet.Backend/Ether/EtherAccount.fs | |
index d8fede4..2bbd7d9 100644 | |
--- a/src/GWallet.Backend/Ether/EtherAccount.fs | |
+++ b/src/GWallet.Backend/Ether/EtherAccount.fs | |
@@ -151,6 +151,27 @@ module internal Account = | |
return gasPrice64 | |
} | |
+ let EstimateGasCostForContractWithDefaultFunction (account: IAccount) (amount: TransferAmount) destination: Async<TransactionMetadata> = async { | |
+ let! gasPrice64 = GetGasPrice account.Currency | |
+ | |
+ | |
+ let! estimateGasForContract = Ether.Server.EstimateGasCostForContract account destination amount.ValueToSend | |
+ if (estimateGasForContract.Value > BigInteger(Int64.MaxValue)) then | |
+ failwith (sprintf "GWallet serialization doesn't support such a big integer (%s) for the gas cost of the ton transfer, please report this issue." | |
+ (estimateGasForContract.Value.ToString())) | |
+ let gasCost64: Int64 = BigInteger.op_Explicit estimateGasForContract.Value | |
+ | |
+ let ethMinerFee = MinerFee(gasCost64, gasPrice64, DateTime.Now, account.Currency) | |
+ let! txCount = GetTransactionCount account.Currency account.PublicAddress | |
+ | |
+ let feeValue = ethMinerFee.CalculateAbsoluteValue() | |
+ if (amount.ValueToSend <> amount.BalanceAtTheMomentOfSending && | |
+ feeValue > (amount.BalanceAtTheMomentOfSending - amount.ValueToSend)) then | |
+ raise (InsufficientBalanceForFee feeValue) | |
+ | |
+ return { Ether.Fee = ethMinerFee; Ether.TransactionCount = txCount } | |
+ } | |
+ | |
let private GAS_COST_FOR_A_NORMAL_ETHER_TRANSACTION:int64 = 21000L | |
let EstimateEtherTransferFee (account: IAccount) (amount: TransferAmount): Async<TransactionMetadata> = async { | |
@@ -188,7 +209,12 @@ module internal Account = | |
let EstimateFee (account: IAccount) (amount: TransferAmount) destination: Async<TransactionMetadata> = async { | |
if account.Currency.IsEther() then | |
- return! EstimateEtherTransferFee account amount | |
+ let! isContract = Ether.Server.CheckIfAddressIsAContractAddress account.Currency destination | |
+ if isContract then | |
+ return! EstimateGasCostForContractWithDefaultFunction account amount destination | |
+ else | |
+ return! EstimateEtherTransferFee account amount | |
elif account.Currency.IsEthToken() then | |
return! EstimateTokenTransferFee account amount.ValueToSend destination | |
else | |
diff --git a/src/GWallet.Backend/Ether/EtherServer.fs b/src/GWallet.Backend/Ether/EtherServer.fs | |
index cfa90f1..b76d967 100644 | |
--- a/src/GWallet.Backend/Ether/EtherServer.fs | |
+++ b/src/GWallet.Backend/Ether/EtherServer.fs | |
@@ -11,6 +11,7 @@ open Nethereum.Hex.HexTypes | |
open Nethereum.Web3 | |
open Nethereum.RPC.Eth.DTOs | |
open Nethereum.StandardTokenEIP20.ContractDefinition | |
+open Nethereum.RPC.TransactionManagers | |
open GWallet.Backend | |
@@ -580,15 +581,41 @@ module Server = | |
web3Funcs | |
} | |
- let CheckIfAddressIsAValidPaymentDestination (currency: Currency) (address: string): Async<unit> = | |
+ let CheckIfAddressIsAContractAddress (currency: Currency) (address: string): Async<bool> = | |
async { | |
let! contractCode = GetContractCode currency address | |
let emptyContract = "0x" | |
if not (contractCode.StartsWith emptyContract) then | |
failwithf "GetCode API should always return a string starting with %s, but got: %s" | |
- emptyContract contractCode | |
- elif contractCode <> emptyContract then | |
- return raise <| InvalidDestinationAddress "Sending to contract addresses is not supported yet. Supply a normal address please." | |
+ emptyContract contractCode | |
+ | |
+ return contractCode <> emptyContract | |
+ | |
+ } | |
+ | |
+ | |
+ let EstimateGasCostForContract (account: IAccount) destination amount: Async<HexBigInteger> = | |
+ async { | |
+ | |
+ let transactionInput = EtherTransferTransactionInputBuilder.CreateTransactionInput(account.PublicAddress, destination, amount) | |
+ //(string fromAddress, string toAddress, decimal etherAmount, decimal? gasPriceGwei = null, BigInteger? gas = null) | |
+ let web3Funcs = | |
+ let web3Func (web3: Web3): Async<HexBigInteger> = | |
+ let estimateGasJob = | |
+ async { | |
+ let task = web3.TransactionManager.EstimateGasAsync(transactionInput) | |
+ return! Async.AwaitTask task | |
+ } | |
+ HandlePossibleEtherFailures estimateGasJob | |
+ GetWeb3Funcs account.Currency web3Func | |
+ | |
+ return! faultTolerantEtherClient.Query | |
+ (FaultTolerantParallelClientDefaultSettings account.Currency Mode.Fast) | |
+ web3Funcs | |
+ | |
} | |
+ | |
+ | |
\ No newline at end of file | |
diff --git a/src/GWallet.Backend/Exceptions.fs b/src/GWallet.Backend/Exceptions.fs | |
index 1edf170..5e60e66 100644 | |
--- a/src/GWallet.Backend/Exceptions.fs | |
+++ b/src/GWallet.Backend/Exceptions.fs | |
@@ -12,6 +12,3 @@ exception AddressWithInvalidLength of seq<int> | |
exception AddressWithInvalidChecksum of Option<string> | |
exception AccountAlreadyAdded | |
- | |
-exception InvalidDestinationAddress of msg: string | |
- | |
diff --git a/src/GWallet.Frontend.Console/Program.fs b/src/GWallet.Frontend.Console/Program.fs | |
index 39e61f3..4e130ea 100644 | |
--- a/src/GWallet.Frontend.Console/Program.fs | |
+++ b/src/GWallet.Frontend.Console/Program.fs | |
@@ -240,7 +240,6 @@ let rec PerformOptions(numAccounts: int) = | |
SendPayment() | |
| Options.AddReadonlyAccounts -> | |
AddReadOnlyAccounts() | |
- |> Async.RunSynchronously | |
| Options.SignOffPayment -> | |
SignOffPayment() | |
| Options.BroadcastPayment -> | |
diff --git a/src/GWallet.Frontend.Console/UserInteraction.fs b/src/GWallet.Frontend.Console/UserInteraction.fs | |
index 50c9fd5..1f0718a 100644 | |
--- a/src/GWallet.Frontend.Console/UserInteraction.fs | |
+++ b/src/GWallet.Frontend.Console/UserInteraction.fs | |
@@ -337,12 +337,8 @@ module UserInteraction = | |
let validatedAddress = | |
try | |
Account.ValidateAddress currency publicAddress | |
- |> Async.RunSynchronously | |
publicAddress | |
with | |
- | InvalidDestinationAddress msg -> | |
- Presentation.Error msg | |
- AskPublicAddress currency askText | |
| AddressMissingProperPrefix(possiblePrefixes) -> | |
let possiblePrefixesStr = String.Join(", ", possiblePrefixes) | |
Presentation.Error (sprintf "Address starts with the wrong prefix. Valid prefixes: %s" | |
(END) | |
| Options.AddReadonlyAccounts -> | |
AddReadOnlyAccounts() | |
- |> Async.RunSynchronously | |
| Options.SignOffPayment -> | |
SignOffPayment() | |
| Options.BroadcastPayment -> | |
diff --git a/src/GWallet.Frontend.Console/UserInteraction.fs b/src/GWallet.Frontend.Console/UserInteraction.fs | |
index 50c9fd5..1f0718a 100644 | |
--- a/src/GWallet.Frontend.Console/UserInteraction.fs | |
+++ b/src/GWallet.Frontend.Console/UserInteraction.fs | |
@@ -337,12 +337,8 @@ module UserInteraction = | |
let validatedAddress = | |
try | |
Account.ValidateAddress currency publicAddress | |
- |> Async.RunSynchronously | |
publicAddress | |
with | |
- | InvalidDestinationAddress msg -> | |
- Presentation.Error msg | |
- AskPublicAddress currency askText | |
| AddressMissingProperPrefix(possiblePrefixes) -> | |
let possiblePrefixesStr = String.Join(", ", possiblePrefixes) | |
Presentation.Error (sprintf "Address starts with the wrong prefix. Valid prefixes: %s" | |
~ | |
(END) | |
| Options.AddReadonlyAccounts -> | |
AddReadOnlyAccounts() | |
- |> Async.RunSynchronously | |
| Options.SignOffPayment -> | |
SignOffPayment() | |
| Options.BroadcastPayment -> | |
diff --git a/src/GWallet.Frontend.Console/UserInteraction.fs b/src/GWallet.Frontend.Console/UserInteraction.fs | |
index 50c9fd5..1f0718a 100644 | |
--- a/src/GWallet.Frontend.Console/UserInteraction.fs | |
+++ b/src/GWallet.Frontend.Console/UserInteraction.fs | |
@@ -337,12 +337,8 @@ module UserInteraction = | |
let validatedAddress = | |
try | |
Account.ValidateAddress currency publicAddress | |
- |> Async.RunSynchronously | |
publicAddress | |
with | |
- | InvalidDestinationAddress msg -> | |
- Presentation.Error msg | |
- AskPublicAddress currency askText | |
| AddressMissingProperPrefix(possiblePrefixes) -> | |
let possiblePrefixesStr = String.Join(", ", possiblePrefixes) | |
Presentation.Error (sprintf "Address starts with the wrong prefix. Valid prefixes: %s" | |
~ | |
~ | |
(END) | |
| Options.AddReadonlyAccounts -> | |
AddReadOnlyAccounts() | |
- |> Async.RunSynchronously | |
| Options.SignOffPayment -> | |
SignOffPayment() | |
| Options.BroadcastPayment -> | |
diff --git a/src/GWallet.Frontend.Console/UserInteraction.fs b/src/GWallet.Frontend.Console/UserInteraction.fs | |
index 50c9fd5..1f0718a 100644 | |
--- a/src/GWallet.Frontend.Console/UserInteraction.fs | |
+++ b/src/GWallet.Frontend.Console/UserInteraction.fs | |
@@ -337,12 +337,8 @@ module UserInteraction = | |
let validatedAddress = | |
try | |
Account.ValidateAddress currency publicAddress | |
- |> Async.RunSynchronously | |
publicAddress | |
with | |
- | InvalidDestinationAddress msg -> | |
- Presentation.Error msg | |
- AskPublicAddress currency askText | |
| AddressMissingProperPrefix(possiblePrefixes) -> | |
let possiblePrefixesStr = String.Join(", ", possiblePrefixes) | |
Presentation.Error (sprintf "Address starts with the wrong prefix. Valid prefixes: %s" | |
~ | |
~ | |
~ | |
(END) | |
| Options.AddReadonlyAccounts -> | |
AddReadOnlyAccounts() | |
- |> Async.RunSynchronously | |
| Options.SignOffPayment -> | |
SignOffPayment() | |
| Options.BroadcastPayment -> | |
diff --git a/src/GWallet.Frontend.Console/UserInteraction.fs b/src/GWallet.Frontend.Console/UserInteraction.fs | |
index 50c9fd5..1f0718a 100644 | |
--- a/src/GWallet.Frontend.Console/UserInteraction.fs | |
+++ b/src/GWallet.Frontend.Console/UserInteraction.fs | |
@@ -337,12 +337,8 @@ module UserInteraction = | |
let validatedAddress = | |
try | |
Account.ValidateAddress currency publicAddress | |
- |> Async.RunSynchronously | |
publicAddress | |
with | |
- | InvalidDestinationAddress msg -> | |
- Presentation.Error msg | |
- AskPublicAddress currency askText | |
| AddressMissingProperPrefix(possiblePrefixes) -> | |
let possiblePrefixesStr = String.Join(", ", possiblePrefixes) | |
Presentation.Error (sprintf "Address starts with the wrong prefix. Valid prefixes: %s" | |
~ | |
~ | |
~ | |
~ | |
~ | |
(END) | |
| Options.AddReadonlyAccounts -> | |
AddReadOnlyAccounts() | |
- |> Async.RunSynchronously | |
| Options.SignOffPayment -> | |
SignOffPayment() | |
| Options.BroadcastPayment -> | |
diff --git a/src/GWallet.Frontend.Console/UserInteraction.fs b/src/GWallet.Frontend.Console/UserInteraction.fs | |
index 50c9fd5..1f0718a 100644 | |
--- a/src/GWallet.Frontend.Console/UserInteraction.fs | |
+++ b/src/GWallet.Frontend.Console/UserInteraction.fs | |
@@ -337,12 +337,8 @@ module UserInteraction = | |
let validatedAddress = | |
try | |
Account.ValidateAddress currency publicAddress | |
- |> Async.RunSynchronously | |
publicAddress | |
with | |
- | InvalidDestinationAddress msg -> | |
- Presentation.Error msg | |
- AskPublicAddress currency askText | |
| AddressMissingProperPrefix(possiblePrefixes) -> | |
let possiblePrefixesStr = String.Join(", ", possiblePrefixes) | |
Presentation.Error (sprintf "Address starts with the wrong prefix. Valid prefixes: %s" | |
~ | |
~ | |
~ | |
~ | |
~ | |
~ | |
(END) | |
| Options.AddReadonlyAccounts -> | |
AddReadOnlyAccounts() | |
- |> Async.RunSynchronously | |
| Options.SignOffPayment -> | |
SignOffPayment() | |
| Options.BroadcastPayment -> | |
diff --git a/src/GWallet.Frontend.Console/UserInteraction.fs b/src/GWallet.Frontend.Console/UserInteraction.fs | |
index 50c9fd5..1f0718a 100644 | |
--- a/src/GWallet.Frontend.Console/UserInteraction.fs | |
+++ b/src/GWallet.Frontend.Console/UserInteraction.fs | |
@@ -337,12 +337,8 @@ module UserInteraction = | |
let validatedAddress = | |
try | |
Account.ValidateAddress currency publicAddress | |
- |> Async.RunSynchronously | |
publicAddress | |
with | |
- | InvalidDestinationAddress msg -> | |
- Presentation.Error msg | |
- AskPublicAddress currency askText | |
| AddressMissingProperPrefix(possiblePrefixes) -> | |
let possiblePrefixesStr = String.Join(", ", possiblePrefixes) | |
Presentation.Error (sprintf "Address starts with the wrong prefix. Valid prefixes: %s" | |
~ | |
~ | |
~ | |
~ | |
~ | |
~ | |
~ | |
~ | |
(END) | |
| Options.AddReadonlyAccounts -> | |
AddReadOnlyAccounts() | |
- |> Async.RunSynchronously | |
| Options.SignOffPayment -> | |
SignOffPayment() | |
| Options.BroadcastPayment -> | |
diff --git a/src/GWallet.Frontend.Console/UserInteraction.fs b/src/GWallet.Frontend.Console/UserInteraction.fs | |
index 50c9fd5..1f0718a 100644 | |
--- a/src/GWallet.Frontend.Console/UserInteraction.fs | |
+++ b/src/GWallet.Frontend.Console/UserInteraction.fs | |
@@ -337,12 +337,8 @@ module UserInteraction = | |
let validatedAddress = | |
try | |
Account.ValidateAddress currency publicAddress | |
- |> Async.RunSynchronously | |
publicAddress | |
with | |
- | InvalidDestinationAddress msg -> | |
- Presentation.Error msg | |
- AskPublicAddress currency askText | |
| AddressMissingProperPrefix(possiblePrefixes) -> | |
let possiblePrefixesStr = String.Join(", ", possiblePrefixes) | |
Presentation.Error (sprintf "Address starts with the wrong prefix. Valid prefixes: %s" | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment