Skip to content

Commit

Permalink
Backend,Frontend.Console: ask when unreasonable fee
Browse files Browse the repository at this point in the history
  • Loading branch information
aarani committed Oct 2, 2023
1 parent 19795ba commit aaa8c2e
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 31 deletions.
18 changes: 10 additions & 8 deletions src/GWallet.Backend/Account.fs
Original file line number Diff line number Diff line change
Expand Up @@ -198,15 +198,15 @@ module Account =
// FIXME: broadcasting shouldn't just get N consistent replies from FaultTolerantClient,
// but send it to as many as possible, otherwise it could happen that some server doesn't
// broadcast it even if you sent it
let BroadcastTransaction (trans: SignedTransaction<_>): Async<Uri> =
let BroadcastTransaction (trans: SignedTransaction<_>) (ignoreHigherMinerFeeThanAmount: bool): Async<Uri> =
async {
let currency = trans.TransactionInfo.Proposal.Amount.Currency

let! txId =
if currency.IsEtherBased() then
Ether.Account.BroadcastTransaction trans
Ether.Account.BroadcastTransaction trans ignoreHigherMinerFeeThanAmount
elif currency.IsUtxo() then
UtxoCoin.Account.BroadcastTransaction currency trans
UtxoCoin.Account.BroadcastTransaction currency trans ignoreHigherMinerFeeThanAmount
else
failwith <| SPrintF1 "Unknown currency %A" currency

Expand Down Expand Up @@ -313,14 +313,15 @@ module Account =
let SweepArchivedFunds (account: ArchivedAccount)
(balance: decimal)
(destination: IAccount)
(txMetadata: IBlockchainFeeInfo) =
(txMetadata: IBlockchainFeeInfo)
(ignoreHigherMinerFeeThanAmount: bool) =
match txMetadata with
| :? Ether.TransactionMetadata as etherTxMetadata ->
Ether.Account.SweepArchivedFunds account balance destination etherTxMetadata
Ether.Account.SweepArchivedFunds account balance destination etherTxMetadata ignoreHigherMinerFeeThanAmount
| :? UtxoCoin.TransactionMetadata as utxoTxMetadata ->
match account with
| :? UtxoCoin.ArchivedUtxoAccount as utxoAccount ->
UtxoCoin.Account.SweepArchivedFunds utxoAccount balance destination utxoTxMetadata
UtxoCoin.Account.SweepArchivedFunds utxoAccount balance destination utxoTxMetadata ignoreHigherMinerFeeThanAmount
| _ ->
failwith "If tx metadata is UTXO type, archived account should be too"
| _ -> failwith "tx metadata type unknown"
Expand All @@ -330,6 +331,7 @@ module Account =
(destination: string)
(amount: TransferAmount)
(password: string)
(ignoreHigherMinerFeeThanAmount: bool)
: Async<Uri> =
let baseAccount = account :> IAccount
if (baseAccount.PublicAddress.Equals(destination, StringComparison.InvariantCultureIgnoreCase)) then
Expand All @@ -348,14 +350,14 @@ module Account =
currency
match account with
| :? UtxoCoin.NormalUtxoAccount as utxoAccount ->
UtxoCoin.Account.SendPayment utxoAccount btcTxMetadata destination amount password
UtxoCoin.Account.SendPayment utxoAccount btcTxMetadata destination amount password ignoreHigherMinerFeeThanAmount
| _ ->
failwith "Account not Utxo-type but tx metadata is? report this bug (sendpayment)"

| :? Ether.TransactionMetadata as etherTxMetadata ->
if not (currency.IsEtherBased()) then
failwith "Account not ether-type but tx metadata is? report this bug (sendpayment)"
Ether.Account.SendPayment account etherTxMetadata destination amount password
Ether.Account.SendPayment account etherTxMetadata destination amount password ignoreHigherMinerFeeThanAmount
| _ ->
failwith "Unknown tx metadata type"

Expand Down
15 changes: 9 additions & 6 deletions src/GWallet.Backend/Ether/EtherAccount.fs
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,9 @@ module internal Account =
if minerFeeInWei > amountInWei then
raise MinerFeeHigherThanOutputs

let private BroadcastRawTransaction (currency: Currency) trans =
ValidateMinerFee trans
let private BroadcastRawTransaction (currency: Currency) trans (ignoreHigherMinerFeeThanAmount: bool) =
if not ignoreHigherMinerFeeThanAmount then
ValidateMinerFee trans
Ether.Server.BroadcastTransaction currency ("0x" + trans)

let BroadcastTransaction (trans: SignedTransaction<_>) =
Expand Down Expand Up @@ -370,19 +371,21 @@ module internal Account =
let SweepArchivedFunds (account: ArchivedAccount)
(balance: decimal)
(destination: IAccount)
(txMetadata: TransactionMetadata) =
(txMetadata: TransactionMetadata)
(ignoreHigherMinerFeeThanAmount: bool) =
let accountFrom = (account:>IAccount)
let amount = TransferAmount(balance, balance, accountFrom.Currency)
let ecPrivKey = EthECKey(account.GetUnencryptedPrivateKey())
let signedTrans = SignTransactionWithPrivateKey
account txMetadata destination.PublicAddress amount ecPrivKey
BroadcastRawTransaction accountFrom.Currency signedTrans
BroadcastRawTransaction accountFrom.Currency signedTrans ignoreHigherMinerFeeThanAmount

let SendPayment (account: NormalAccount)
(txMetadata: TransactionMetadata)
(destination: string)
(amount: TransferAmount)
(password: string) =
(password: string)
(ignoreHigherMinerFeeThanAmount: bool) =
let baseAccount = account :> IAccount
if (baseAccount.PublicAddress.Equals(destination, StringComparison.InvariantCultureIgnoreCase)) then
raise DestinationEqualToOrigin
Expand All @@ -391,7 +394,7 @@ module internal Account =

let trans = SignTransaction account txMetadata destination amount password

BroadcastRawTransaction currency trans
BroadcastRawTransaction currency trans ignoreHigherMinerFeeThanAmount

let private CreateInternal (password: string) (seed: array<byte>): FileRepresentation =
let privateKey = EthECKey(seed, true)
Expand Down
11 changes: 7 additions & 4 deletions src/GWallet.Backend/UtxoCoin/UtxoCoinAccount.fs
Original file line number Diff line number Diff line change
Expand Up @@ -427,9 +427,10 @@ module Account =
return ()
}

let private BroadcastRawTransaction currency (rawTx: string): Async<string> =
let private BroadcastRawTransaction currency (rawTx: string) (ignoreHigherMinerFeeThanAmount: bool): Async<string> =
async {
do! ValidateMinerFee currency rawTx
if not ignoreHigherMinerFeeThanAmount then
do! ValidateMinerFee currency rawTx
let job = ElectrumClient.BroadcastTransaction rawTx
return! Server.Query currency QuerySettings.Broadcast job None
}
Expand All @@ -444,13 +445,14 @@ module Account =
(destination: string)
(amount: TransferAmount)
(password: string)
(ignoreHigherMinerFeeThanAmount: bool)
=
let baseAccount = account :> IAccount
if (baseAccount.PublicAddress.Equals(destination, StringComparison.InvariantCultureIgnoreCase)) then
raise DestinationEqualToOrigin

let finalTransaction = SignTransaction account txMetadata destination amount password
BroadcastRawTransaction baseAccount.Currency finalTransaction
BroadcastRawTransaction baseAccount.Currency finalTransaction ignoreHigherMinerFeeThanAmount

// TODO: maybe move this func to Backend.Account module, or simply inline it (simple enough)
let public ExportUnsignedTransactionToJson trans =
Expand All @@ -473,14 +475,15 @@ module Account =
(balance: decimal)
(destination: IAccount)
(txMetadata: TransactionMetadata)
(ignoreHigherMinerFeeThanAmount: bool)
=
let currency = (account:>IAccount).Currency
let network = GetNetwork currency
let amount = TransferAmount(balance, balance, currency)
let privateKey = Key.Parse(account.GetUnencryptedPrivateKey(), network)
let signedTrans = SignTransactionWithPrivateKey
account txMetadata destination.PublicAddress amount privateKey
BroadcastRawTransaction currency (signedTrans.ToHex())
BroadcastRawTransaction currency (signedTrans.ToHex()) ignoreHigherMinerFeeThanAmount

let internal Create currency (password: string) (seed: array<byte>): Async<FileRepresentation> =
async {
Expand Down
47 changes: 34 additions & 13 deletions src/GWallet.Frontend.Console/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,31 @@ open System.Text.RegularExpressions
open GWallet.Backend
open GWallet.Frontend.Console

let SendWithMinerFeeValidation (sendPaymentFunc: bool -> unit) =
try
sendPaymentFunc false

UserInteraction.PressAnyKeyToContinue ()
with
| :? MinerFeeHigherThanOutputs ->
let userWantsToContinue =
UserInteraction.AskYesNo "Miner fee is higher than amount transferred, are you ABSOLUTELY sure you want to broadcast?"
if userWantsToContinue then
sendPaymentFunc true

UserInteraction.PressAnyKeyToContinue ()

let rec TrySendAmount (account: NormalAccount) transactionMetadata destination amount =
let password = UserInteraction.AskPassword false
try

let sendPayment ignoreHigherMinerFeeThanAmount =
let txIdUri =
Account.SendPayment account transactionMetadata destination amount password
Account.SendPayment account transactionMetadata destination amount password ignoreHigherMinerFeeThanAmount
|> Async.RunSynchronously
Console.WriteLine(sprintf "Transaction successful:%s%s" Environment.NewLine (txIdUri.ToString()))
UserInteraction.PressAnyKeyToContinue ()

try
SendWithMinerFeeValidation sendPayment
with
| :? DestinationEqualToOrigin ->
Presentation.Error "Transaction's origin cannot be the same as the destination."
Expand Down Expand Up @@ -69,11 +86,13 @@ let BroadcastPayment() =

if UserInteraction.AskYesNo "Do you accept?" then
try
let txIdUri =
Account.BroadcastTransaction signedTransaction
|> Async.RunSynchronously
Console.WriteLine(sprintf "Transaction successful:%s%s" Environment.NewLine (txIdUri.ToString()))
UserInteraction.PressAnyKeyToContinue ()
let broadcastTx ignoreHigherMinerFeeThanAmount =
let txIdUri =
Account.BroadcastTransaction signedTransaction ignoreHigherMinerFeeThanAmount
|> Async.RunSynchronously
Console.WriteLine(sprintf "Transaction successful:%s%s" Environment.NewLine (txIdUri.ToString()))

SendWithMinerFeeValidation broadcastTx
with
| :? DestinationEqualToOrigin ->
Presentation.Error "Transaction's origin cannot be the same as the destination."
Expand Down Expand Up @@ -413,11 +432,13 @@ let rec CheckArchivedAccountsAreEmpty(): bool =
match maybeFee with
| None -> ()
| Some(feeInfo) ->
let txId =
Account.SweepArchivedFunds archivedAccount balance account feeInfo
|> Async.RunSynchronously
Console.WriteLine(sprintf "Transaction successful, its ID is:%s%s" Environment.NewLine txId)
UserInteraction.PressAnyKeyToContinue ()
let sweepFunds ignoreHigherMinerFeeThanAmount =
let txId =
Account.SweepArchivedFunds archivedAccount balance account feeInfo ignoreHigherMinerFeeThanAmount
|> Async.RunSynchronously
Console.WriteLine(sprintf "Transaction successful, its ID is:%s%s" Environment.NewLine txId)

SendWithMinerFeeValidation sweepFunds

not (archivedAccountsInNeedOfAction.Any())

Expand Down

0 comments on commit aaa8c2e

Please sign in to comment.