mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-11-24 22:45:50 +00:00
Merge 4c10273fb1748acefcd96b85df49de8664473d15 into 7a61c637b0641002abc30ecf2e7e5729ab3cab20
This commit is contained in:
commit
7d719d1237
@ -1,6 +1,6 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.28.0
|
// protoc-gen-go v1.26.0
|
||||||
// protoc v3.17.2
|
// protoc v3.17.2
|
||||||
// source: kaspawalletd.proto
|
// source: kaspawalletd.proto
|
||||||
|
|
||||||
|
|||||||
@ -13,9 +13,6 @@ import (
|
|||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: Implement a better fee estimation mechanism
|
|
||||||
const feePerInput = 10000
|
|
||||||
|
|
||||||
func (s *server) CreateUnsignedTransactions(_ context.Context, request *pb.CreateUnsignedTransactionsRequest) (
|
func (s *server) CreateUnsignedTransactions(_ context.Context, request *pb.CreateUnsignedTransactionsRequest) (
|
||||||
*pb.CreateUnsignedTransactionsResponse, error,
|
*pb.CreateUnsignedTransactionsResponse, error,
|
||||||
) {
|
) {
|
||||||
@ -56,7 +53,7 @@ func (s *server) createUnsignedTransactions(address string, amount uint64, fromA
|
|||||||
fromAddresses = append(fromAddresses, fromAddress)
|
fromAddresses = append(fromAddresses, fromAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
selectedUTXOs, changeSompi, err := s.selectUTXOs(amount, feePerInput, fromAddresses)
|
selectedUTXOs, changeSompi, err := s.selectUTXOs(amount, libkaspawallet.FeePerInput, fromAddresses)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -55,7 +55,7 @@ func (s *server) selectExternalSpendableUTXOs(externalUTXOs *appmessage.GetUTXOs
|
|||||||
func isExternalUTXOSpendable(entry *appmessage.UTXOsByAddressesEntry, virtualDAAScore uint64, coinbaseMaturity uint64) bool {
|
func isExternalUTXOSpendable(entry *appmessage.UTXOsByAddressesEntry, virtualDAAScore uint64, coinbaseMaturity uint64) bool {
|
||||||
if !entry.UTXOEntry.IsCoinbase {
|
if !entry.UTXOEntry.IsCoinbase {
|
||||||
return true
|
return true
|
||||||
} else if entry.UTXOEntry.Amount <= feePerInput {
|
} else if entry.UTXOEntry.Amount <= libkaspawallet.FeePerInput {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return entry.UTXOEntry.BlockDAAScore+coinbaseMaturity < virtualDAAScore
|
return entry.UTXOEntry.BlockDAAScore+coinbaseMaturity < virtualDAAScore
|
||||||
|
|||||||
@ -71,7 +71,7 @@ func (s *server) mergeTransaction(
|
|||||||
DerivationPath: s.walletAddressPath(changeWalletAddress),
|
DerivationPath: s.walletAddressPath(changeWalletAddress),
|
||||||
}
|
}
|
||||||
totalValue += output.Value
|
totalValue += output.Value
|
||||||
totalValue -= feePerInput
|
totalValue -= libkaspawallet.FeePerInput
|
||||||
}
|
}
|
||||||
|
|
||||||
if totalValue < sentValue {
|
if totalValue < sentValue {
|
||||||
@ -206,7 +206,7 @@ func (s *server) createSplitTransaction(transaction *serialization.PartiallySign
|
|||||||
})
|
})
|
||||||
|
|
||||||
totalSompi += selectedUTXOs[i-startIndex].UTXOEntry.Amount()
|
totalSompi += selectedUTXOs[i-startIndex].UTXOEntry.Amount()
|
||||||
totalSompi -= feePerInput
|
totalSompi -= libkaspawallet.FeePerInput
|
||||||
}
|
}
|
||||||
unsignedTransactionBytes, err := libkaspawallet.CreateUnsignedTransaction(s.keysFile.ExtendedPublicKeys,
|
unsignedTransactionBytes, err := libkaspawallet.CreateUnsignedTransaction(s.keysFile.ExtendedPublicKeys,
|
||||||
s.keysFile.MinimumSignatures,
|
s.keysFile.MinimumSignatures,
|
||||||
@ -271,7 +271,7 @@ func (s *server) moreUTXOsForMergeTransaction(alreadySelectedUTXOs []*libkaspawa
|
|||||||
Outpoint: utxo.Outpoint,
|
Outpoint: utxo.Outpoint,
|
||||||
UTXOEntry: utxo.UTXOEntry,
|
UTXOEntry: utxo.UTXOEntry,
|
||||||
DerivationPath: s.walletAddressPath(utxo.address)})
|
DerivationPath: s.walletAddressPath(utxo.address)})
|
||||||
totalValueAdded += utxo.UTXOEntry.Amount() - feePerInput
|
totalValueAdded += utxo.UTXOEntry.Amount() - libkaspawallet.FeePerInput
|
||||||
if totalValueAdded >= requiredAmount {
|
if totalValueAdded >= requiredAmount {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|||||||
54
cmd/kaspawallet/libkaspawallet/fees.go
Normal file
54
cmd/kaspawallet/libkaspawallet/fees.go
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package libkaspawallet
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
|
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO: Implement a better fee construction and estimation mechanism.
|
||||||
|
|
||||||
|
//FeePerInput is the current constant per input to pay for transactions.
|
||||||
|
const FeePerInput uint64 = 10000
|
||||||
|
|
||||||
|
//CalculateFees calculates the totalFee for a slice of transactions
|
||||||
|
func CalculateFees(transactions []*externalapi.DomainTransaction) (uint64, error) {
|
||||||
|
|
||||||
|
var totalFee uint64
|
||||||
|
|
||||||
|
for _, tx := range transactions {
|
||||||
|
fee, err := CalculateFee(tx)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
totalFee += fee
|
||||||
|
}
|
||||||
|
|
||||||
|
return totalFee, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//CalculateFee calculates fee for a transaction
|
||||||
|
func CalculateFee(transaction *externalapi.DomainTransaction) (uint64, error) {
|
||||||
|
|
||||||
|
var totalInputAmount uint64
|
||||||
|
var totalOutputAmount uint64
|
||||||
|
|
||||||
|
for _, input := range transaction.Inputs {
|
||||||
|
totalInputAmount += input.UTXOEntry.Amount()
|
||||||
|
}
|
||||||
|
for _, output := range transaction.Outputs {
|
||||||
|
totalOutputAmount += output.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
return CalculateFeeFromInputAndOutputTotalAmounts(totalInputAmount, totalOutputAmount)
|
||||||
|
}
|
||||||
|
|
||||||
|
//CalculateFeeFromInputAndOutputTotalAmounts calculates tx fee form total input and output amounts
|
||||||
|
//this func is more performant then CalculateFee if total input and output amounts are knowen.
|
||||||
|
func CalculateFeeFromInputAndOutputTotalAmounts(totalInputAmount uint64, totalOutputAmount uint64) (uint64, error) {
|
||||||
|
if totalInputAmount > totalOutputAmount {
|
||||||
|
return 0, errors.Errorf("The input amount may not exceed the output amount, Cannot Calculate negative fees")
|
||||||
|
}
|
||||||
|
|
||||||
|
return totalInputAmount - totalOutputAmount, nil
|
||||||
|
}
|
||||||
@ -3,13 +3,15 @@ package main
|
|||||||
import (
|
import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/kaspanet/kaspad/cmd/kaspawallet/libkaspawallet"
|
||||||
"github.com/kaspanet/kaspad/cmd/kaspawallet/libkaspawallet/serialization"
|
"github.com/kaspanet/kaspad/cmd/kaspawallet/libkaspawallet/serialization"
|
||||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
|
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
|
||||||
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
|
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
|
||||||
"github.com/kaspanet/kaspad/domain/consensus/utils/txscript"
|
"github.com/kaspanet/kaspad/domain/consensus/utils/txscript"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"io/ioutil"
|
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func parse(conf *parseConfig) error {
|
func parse(conf *parseConfig) error {
|
||||||
@ -42,7 +44,6 @@ func parse(conf *parseConfig) error {
|
|||||||
|
|
||||||
fmt.Printf("Transaction #%d ID: \t%s\n", i+1, consensushashing.TransactionID(partiallySignedTransaction.Tx))
|
fmt.Printf("Transaction #%d ID: \t%s\n", i+1, consensushashing.TransactionID(partiallySignedTransaction.Tx))
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
|
|
||||||
allInputSompi := uint64(0)
|
allInputSompi := uint64(0)
|
||||||
for index, input := range partiallySignedTransaction.Tx.Inputs {
|
for index, input := range partiallySignedTransaction.Tx.Inputs {
|
||||||
partiallySignedInput := partiallySignedTransaction.PartiallySignedInputs[index]
|
partiallySignedInput := partiallySignedTransaction.PartiallySignedInputs[index]
|
||||||
@ -51,7 +52,6 @@ func parse(conf *parseConfig) error {
|
|||||||
fmt.Printf("Input %d: \tOutpoint: %s:%d \tAmount: %.2f Kaspa\n", index, input.PreviousOutpoint.TransactionID,
|
fmt.Printf("Input %d: \tOutpoint: %s:%d \tAmount: %.2f Kaspa\n", index, input.PreviousOutpoint.TransactionID,
|
||||||
input.PreviousOutpoint.Index, float64(partiallySignedInput.PrevOutput.Value)/float64(constants.SompiPerKaspa))
|
input.PreviousOutpoint.Index, float64(partiallySignedInput.PrevOutput.Value)/float64(constants.SompiPerKaspa))
|
||||||
}
|
}
|
||||||
|
|
||||||
allInputSompi += partiallySignedInput.PrevOutput.Value
|
allInputSompi += partiallySignedInput.PrevOutput.Value
|
||||||
}
|
}
|
||||||
if conf.Verbose {
|
if conf.Verbose {
|
||||||
@ -73,12 +73,18 @@ func parse(conf *parseConfig) error {
|
|||||||
|
|
||||||
fmt.Printf("Output %d: \tRecipient: %s \tAmount: %.2f Kaspa\n",
|
fmt.Printf("Output %d: \tRecipient: %s \tAmount: %.2f Kaspa\n",
|
||||||
index, addressString, float64(output.Value)/float64(constants.SompiPerKaspa))
|
index, addressString, float64(output.Value)/float64(constants.SompiPerKaspa))
|
||||||
|
|
||||||
allOutputSompi += output.Value
|
allOutputSompi += output.Value
|
||||||
|
|
||||||
}
|
}
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
|
|
||||||
fmt.Printf("Fee:\t%d Sompi\n\n", allInputSompi-allOutputSompi)
|
fee, err := libkaspawallet.CalculateFeeFromInputAndOutputTotalAmounts(allInputSompi, allOutputSompi)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Fee:\t%d Sompi\n\n", fee)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@ -24,8 +24,6 @@ import (
|
|||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
const feePerInput = 10000
|
|
||||||
|
|
||||||
func sweep(conf *sweepConfig) error {
|
func sweep(conf *sweepConfig) error {
|
||||||
|
|
||||||
privateKeyBytes, err := hex.DecodeString(conf.PrivateKey)
|
privateKeyBytes, err := hex.DecodeString(conf.PrivateKey)
|
||||||
@ -89,7 +87,7 @@ func sweep(conf *sweepConfig) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
splitTransactions, err := createSplitTransactionsWithSchnorrPrivteKey(conf.NetParams(), UTXOs, toAddress, feePerInput)
|
splitTransactions, err := createSplitTransactionsWithSchnorrPrivteKey(conf.NetParams(), UTXOs, toAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -141,8 +139,7 @@ func newDummyTransaction() *externalapi.DomainTransaction {
|
|||||||
func createSplitTransactionsWithSchnorrPrivteKey(
|
func createSplitTransactionsWithSchnorrPrivteKey(
|
||||||
params *dagconfig.Params,
|
params *dagconfig.Params,
|
||||||
selectedUTXOs []*libkaspawallet.UTXO,
|
selectedUTXOs []*libkaspawallet.UTXO,
|
||||||
toAddress util.Address,
|
toAddress util.Address) ([]*externalapi.DomainTransaction, error) {
|
||||||
feePerInput int) ([]*externalapi.DomainTransaction, error) {
|
|
||||||
|
|
||||||
var splitTransactions []*externalapi.DomainTransaction
|
var splitTransactions []*externalapi.DomainTransaction
|
||||||
|
|
||||||
@ -180,7 +177,7 @@ func createSplitTransactionsWithSchnorrPrivteKey(
|
|||||||
)
|
)
|
||||||
|
|
||||||
currentTx.Outputs[0] = &externalapi.DomainTransactionOutput{
|
currentTx.Outputs[0] = &externalapi.DomainTransactionOutput{
|
||||||
Value: totalSplitAmount - uint64(len(currentTx.Inputs)*feePerInput),
|
Value: totalSplitAmount - uint64(len(currentTx.Inputs)*int(libkaspawallet.FeePerInput)),
|
||||||
ScriptPublicKey: scriptPublicKey,
|
ScriptPublicKey: scriptPublicKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user