From 18cc32e0e1f5b9203a7b3b16b9b208225b7708b7 Mon Sep 17 00:00:00 2001 From: giangnamnabka Date: Thu, 22 Jun 2023 16:13:39 +0700 Subject: [PATCH] update mintspark estimated fee --- src/renderer/components/SendPage.vue | 4 + src/renderer/components/SendPage/SendFlow.vue | 8 +- src/store/modules/Transactions.ts | 78 ++++++++++++++----- 3 files changed, 68 insertions(+), 22 deletions(-) diff --git a/src/renderer/components/SendPage.vue b/src/renderer/components/SendPage.vue index 8aad5680..874daf69 100644 --- a/src/renderer/components/SendPage.vue +++ b/src/renderer/components/SendPage.vue @@ -561,6 +561,10 @@ export default { this.address = ''; }, + isTransparentAddress() { + return isValidAddress(this.address, this.network); + }, + async validateSparkAddress() { let res = await $daemon.validateSparkAddress(this.address); this.isSparkAddr = res.valid; diff --git a/src/renderer/components/SendPage/SendFlow.vue b/src/renderer/components/SendPage/SendFlow.vue index fb91455d..5af79a34 100644 --- a/src/renderer/components/SendPage/SendFlow.vue +++ b/src/renderer/components/SendPage/SendFlow.vue @@ -190,19 +190,19 @@ export default { } else if (this.isPrivate && !this.isSpark) { // Under the hood we'll always use coin control because the daemon uses a very complex stochastic // algorithm that interferes with fee calculation. - const coinControl = this.coinControl || this.selectInputs(true, false, this.$parent.isSparkAddr, this.amount, this.txFeePerKb, this.subtractFeeFromAmount); + const coinControl = this.coinControl || this.selectInputs(true, false, this.$parent.isTransparentAddress, this.amount, this.txFeePerKb, this.subtractFeeFromAmount); await $daemon.sendLelantus(passphrase, this.address, this.amount, this.txFeePerKb, this.subtractFeeFromAmount, coinControl); } else if (this.isPrivate && this.isSpark) { // Under the hood we'll always use coin control because the daemon uses a very complex stochastic // algorithm that interferes with fee calculation. - const coinControl = this.coinControl || this.selectInputs(true, true, this.$parent.isSparkAddr, this.amount, this.txFeePerKb, this.subtractFeeFromAmount); + const coinControl = this.coinControl || this.selectInputs(true, true, this.$parent.isTransparentAddress, this.amount, this.txFeePerKb, this.subtractFeeFromAmount); await $daemon.spendSpark(passphrase, this.label, this.address, this.amount, this.txFeePerKb, this.subtractFeeFromAmount, coinControl); } else if (!this.isPrivate && this.isSpark && this.$parent.isSparkAddr) { // Under the hood we'll always use coin control because the daemon uses a very complex stochastic // algorithm that interferes with fee calculation. - const coinControl = this.coinControl || this.selectInputs(false, true, this.$parent.isSparkAddr, this.amount, this.txFeePerKb, this.subtractFeeFromAmount); + const coinControl = this.coinControl || this.selectInputs(false, true, this.$parent.isTransparentAddress, this.amount, this.txFeePerKb, this.subtractFeeFromAmount); await $daemon.mintSpark(passphrase, this.label, this.address, this.amount, this.txFeePerKb, this.subtractFeeFromAmount, coinControl); } else { @@ -215,7 +215,7 @@ export default { // Under the hood we'll always use coin control because the daemon uses a very complex stochastic // algorithm that interferes with fee calculation. - const coinControl = this.coinControl || this.selectInputs(false, false, this.$parent.isSparkAddr, this.amount, this.txFeePerKb, this.subtractFeeFromAmount); + const coinControl = this.coinControl || this.selectInputs(false, false, this.$parent.isTransparentAddress, this.amount, this.txFeePerKb, this.subtractFeeFromAmount); await $daemon.publicSend(passphrase, this.label, this.address, this.amount, this.txFeePerKb, this.subtractFeeFromAmount, coinControl); } diff --git a/src/store/modules/Transactions.ts b/src/store/modules/Transactions.ts index 35c4f7eb..1ca37d84 100644 --- a/src/store/modules/Transactions.ts +++ b/src/store/modules/Transactions.ts @@ -155,13 +155,31 @@ function selectUTXOs(isPrivate: boolean, isSpark: boolean, istransparentaddress: } if (coinControl) { + let totalSize = 0n; + let gathered = 0n; + let fee = 0n; if (availableUTXOs.find(utxo => utxo.isPrivate != isPrivate)) return undefined; - // assume 5000 as the signature size for unknown outputs. - const totalSize = constantSize + availableUTXOs.reduce((a, utxo) => a + BigInt(utxo.spendSize) || 5000n, 0n); - const gathered = availableUTXOs.reduce((a, utxo) => a + utxo.amount, 0n); + if (!isPrivate && isSpark && !istransparentaddress) { + let destinations = []; + for (const utxo of availableUTXOs) { + if(!destinations.includes(utxo.destination)) { + totalSize+= constantSize + BigInt(utxo.spendSize) || 5000n; + destinations.push(utxo.destination); + } else { + totalSize += BigInt(utxo.spendSize) || 5000n; + } + gathered += utxo.amount; + if (gathered >= (subtractFeeFromAmount ? amount : amount + fee)) + break; + } + } else { + // assume 5000 as the signature size for unknown outputs. + totalSize = constantSize + availableUTXOs.reduce((a, utxo) => a + BigInt(utxo.spendSize) || 5000n, 0n); + gathered = availableUTXOs.reduce((a, utxo) => a + utxo.amount, 0n); + } - let fee = (totalSize * feePerKb) / 1000n ; + fee = (totalSize * feePerKb) / 1000n ; if (fee === 0n) fee = 1n; if (subtractFeeFromAmount && fee >= amount) return undefined; @@ -176,23 +194,47 @@ function selectUTXOs(isPrivate: boolean, isSpark: boolean, istransparentaddress: .filter(utxo => utxo.isPrivate == isPrivate) .sort((a, b) => Number(b.amount - a.amount)); - let totalSize = constantSize; let gathered = 0n; const selectedUTXOs = []; - while (utxos.length) { - const utxo = utxos.length % 2 ? utxos.shift() : utxos.pop(); - - gathered += utxo.amount; - totalSize += BigInt(utxo.spendSize); - selectedUTXOs.push(utxo); - - let fee = (totalSize * feePerKb) / 1000n; - if (fee === 0n) fee = 1n; - - if (subtractFeeFromAmount && amount <= fee) continue; - if (gathered >= (subtractFeeFromAmount ? amount : amount + fee)) { - return [fee, selectedUTXOs]; + if (!isPrivate && isSpark && !istransparentaddress) { + let destinations = []; + let totalSize = 0n; + while (utxos.length) { + const utxo = utxos.length % 2 ? utxos.shift() : utxos.pop(); + if(!destinations.includes(utxo.destination)) { + totalSize+= constantSize + BigInt(utxo.spendSize); + destinations.push(utxo.destination); + } else { + totalSize += BigInt(utxo.spendSize); + } + + gathered += utxo.amount; + selectedUTXOs.push(utxo); + + let fee = (totalSize * feePerKb) / 1000n; + if (fee === 0n) fee = 1n; + + if (subtractFeeFromAmount && amount <= fee) continue; + if (gathered >= (subtractFeeFromAmount ? amount : amount + fee)) { + return [fee, selectedUTXOs]; + } + } + } else { + let totalSize = constantSize; + while (utxos.length) { + const utxo = utxos.length % 2 ? utxos.shift() : utxos.pop(); + gathered += utxo.amount; + totalSize += BigInt(utxo.spendSize); + selectedUTXOs.push(utxo); + + let fee = (totalSize * feePerKb) / 1000n; + if (fee === 0n) fee = 1n; + + if (subtractFeeFromAmount && amount <= fee) continue; + if (gathered >= (subtractFeeFromAmount ? amount : amount + fee)) { + return [fee, selectedUTXOs]; + } } }