mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-03-30 15:08:33 +00:00

* Add fee estimation to wallet * Add fee rate to kaspawallet parse * Update go version * Get rid of golint * Add RBF support to wallet * Fix bump_fee UTXO lookup and fix wrong change address * impl storage mass as per KIP9 * Use CalculateTransactionOverallMass where needed * Some fixes * Minor typos * Fix test * update version * BroadcastRBF -> BroadcastReplacement * rc3 * align proto files to only use camel case (fixed on RK as well) * Rename to FeePolicy and add MaxFee option + todo * apply max fee constrains * increase minChangeTarget to 10kas * fmt * Some fixes * fix description: maximum -> minimum * put min feerate check in the correct location * Fix calculateFeeLimits nil handling * Add validations to CLI flags * Change to rc6 * Add checkTransactionFeeRate * Add failed broadcast transactions on send error` * Fix estimateFee change value * Estimate fee correctly for --send-all * On estimateFee always assume that the recipient has ECDSA address * remove patch version --------- Co-authored-by: Michael Sutton <msutton@cs.huji.ac.il>
76 lines
2.1 KiB
Go
76 lines
2.1 KiB
Go
package server
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/kaspanet/kaspad/app/appmessage"
|
|
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/pb"
|
|
"github.com/kaspanet/kaspad/cmd/kaspawallet/libkaspawallet"
|
|
"github.com/kaspanet/kaspad/util"
|
|
)
|
|
|
|
func (s *server) GetExternalSpendableUTXOs(_ context.Context, request *pb.GetExternalSpendableUTXOsRequest) (*pb.GetExternalSpendableUTXOsResponse, error) {
|
|
s.lock.RLock()
|
|
defer s.lock.RUnlock()
|
|
|
|
_, err := util.DecodeAddress(request.Address, s.params.Prefix)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
externalUTXOs, err := s.rpcClient.GetUTXOsByAddresses([]string{request.Address})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
estimate, err := s.rpcClient.GetFeeEstimate()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
feeRate := estimate.Estimate.NormalBuckets[0].Feerate
|
|
|
|
selectedUTXOs, err := s.selectExternalSpendableUTXOs(externalUTXOs, feeRate)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &pb.GetExternalSpendableUTXOsResponse{
|
|
Entries: selectedUTXOs,
|
|
}, nil
|
|
}
|
|
|
|
func (s *server) selectExternalSpendableUTXOs(externalUTXOs *appmessage.GetUTXOsByAddressesResponseMessage, feeRate float64) ([]*pb.UtxosByAddressesEntry, error) {
|
|
dagInfo, err := s.rpcClient.GetBlockDAGInfo()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
daaScore := dagInfo.VirtualDAAScore
|
|
maturity := s.params.BlockCoinbaseMaturity
|
|
|
|
//we do not make because we do not know size, because of unspendable utxos
|
|
var selectedExternalUtxos []*pb.UtxosByAddressesEntry
|
|
|
|
feePerInput, err := s.estimateFeePerInput(feeRate)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for _, entry := range externalUTXOs.Entries {
|
|
if !isExternalUTXOSpendable(entry, daaScore, maturity, feePerInput) {
|
|
continue
|
|
}
|
|
selectedExternalUtxos = append(selectedExternalUtxos, libkaspawallet.AppMessageUTXOToKaspawalletdUTXO(entry))
|
|
}
|
|
|
|
return selectedExternalUtxos, nil
|
|
}
|
|
|
|
func isExternalUTXOSpendable(entry *appmessage.UTXOsByAddressesEntry, virtualDAAScore uint64, coinbaseMaturity uint64, feePerInput uint64) bool {
|
|
if !entry.UTXOEntry.IsCoinbase {
|
|
return true
|
|
} else if entry.UTXOEntry.Amount <= feePerInput {
|
|
return false
|
|
}
|
|
return entry.UTXOEntry.BlockDAAScore+coinbaseMaturity < virtualDAAScore
|
|
}
|