Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add optional UTXOs counting to the balance report #2077

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 26 additions & 6 deletions cmd/kaspawallet/balance.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,35 @@ func balance(conf *balanceConfig) error {
}
if conf.Verbose {
pendingSuffix = ""
println("Address Available Pending")
println("-----------------------------------------------------------------------------------------------------------")
for _, addressBalance := range response.AddressBalances {
fmt.Printf("%s %s %s\n", addressBalance.Address, utils.FormatKas(addressBalance.Available), utils.FormatKas(addressBalance.Pending))
if conf.CountUtxos {
println("Address Available #UTXOs Pending #UTXOs")
println("-----------------------------------------------------------------------------------------------------------------------------")
for _, addressBalance := range response.AddressBalances {
fmt.Printf("%s %s %s %s %s\n", addressBalance.Address, utils.FormatKas(addressBalance.Available),
utils.FormatUtxos(addressBalance.NUtxosAvailable), utils.FormatKas(addressBalance.Pending),
utils.FormatUtxos(addressBalance.NUtxosPending))
}
println("-----------------------------------------------------------------------------------------------------------------------------")
} else {
println("Address Available Pending")
println("-----------------------------------------------------------------------------------------------------------")
for _, addressBalance := range response.AddressBalances {
fmt.Printf("%s %s %s\n", addressBalance.Address, utils.FormatKas(addressBalance.Available), utils.FormatKas(addressBalance.Pending))
}
println("-----------------------------------------------------------------------------------------------------------")
}
println("-----------------------------------------------------------------------------------------------------------")
print(" ")
}
fmt.Printf("Total balance, KAS %s %s%s\n", utils.FormatKas(response.Available), utils.FormatKas(response.Pending), pendingSuffix)
if conf.CountUtxos {
if response.Pending > 0 {
fmt.Printf("Total balance, KAS %s (%d UTXOs) %s pending (%d UTXOs)\n", utils.FormatKas(response.Available),
response.NUtxosAvailable, utils.FormatKas(response.Pending), response.NUtxosPending)
} else {
fmt.Printf("Total balance, KAS %s (%d UTXOs)\n", utils.FormatKas(response.Available), response.NUtxosAvailable)
}
} else {
fmt.Printf("Total balance, KAS %s %s%s\n", utils.FormatKas(response.Available), utils.FormatKas(response.Pending), pendingSuffix)
}

return nil
}
2 changes: 1 addition & 1 deletion cmd/kaspawallet/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ type createConfig struct {
type balanceConfig struct {
DaemonAddress string `long:"daemonaddress" short:"d" description:"Wallet daemon server to connect to"`
Verbose bool `long:"verbose" short:"v" description:"Verbose: show addresses with balance"`
CountUtxos bool `long:"count-utxos" short:"u" description:"Display the number of UTXOs constituting a balance"`
config.NetworkFlags
}

Expand Down Expand Up @@ -181,7 +182,6 @@ func parseCommandLine() (subCommand string, config interface{}) {
parser.AddCommand(startDaemonSubCmd, "Start the wallet daemon", "Start the wallet daemon", startDaemonConf)

_, err := parser.Parse()

if err != nil {
var flagsErr *flags.Error
if ok := errors.As(err, &flagsErr); ok && flagsErr.Type == flags.ErrHelp {
Expand Down
360 changes: 201 additions & 159 deletions cmd/kaspawallet/daemon/pb/kaspawalletd.pb.go

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion cmd/kaspawallet/daemon/pb/kaspawalletd.proto
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,17 @@ message GetBalanceRequest {
message GetBalanceResponse {
uint64 available = 1;
uint64 pending = 2;
repeated AddressBalances addressBalances = 3;
uint64 nUtxosAvailable = 3;
uint64 nUtxosPending = 4;
repeated AddressBalances addressBalances = 5;
}

message AddressBalances {
string address = 1;
uint64 available = 2;
uint64 pending = 3;
uint64 nUtxosAvailable = 4;
uint64 nUtxosPending = 5;
}

message CreateUnsignedTransactionsRequest {
Expand Down
2 changes: 1 addition & 1 deletion cmd/kaspawallet/daemon/pb/kaspawalletd_grpc.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 16 additions & 6 deletions cmd/kaspawallet/daemon/server/balance.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import (
"github.com/kaspanet/kaspad/cmd/kaspawallet/libkaspawallet"
)

type balancesType struct{ available, pending uint64 }
type balancesMapType map[*walletAddress]*balancesType
type (
balancesType struct{ available, pending, nUtxosAvailable, nUtxosPending uint64 }
balancesMapType map[*walletAddress]*balancesType
)

func (s *server) GetBalance(_ context.Context, _ *pb.GetBalanceRequest) (*pb.GetBalanceResponse, error) {
s.lock.RLock()
Expand All @@ -32,32 +34,40 @@ func (s *server) GetBalance(_ context.Context, _ *pb.GetBalanceRequest) (*pb.Get
}
if isUTXOSpendable(entry, daaScore, maturity) {
balances.available += amount
balances.nUtxosAvailable++
} else {
balances.pending += amount
balances.nUtxosPending++
}
}

addressBalances := make([]*pb.AddressBalances, len(balancesMap))
i := 0
var available, pending uint64
var available, pending, nUtxosAvailable, nUtxosPending uint64
for walletAddress, balances := range balancesMap {
address, err := libkaspawallet.Address(s.params, s.keysFile.ExtendedPublicKeys, s.keysFile.MinimumSignatures, s.walletAddressPath(walletAddress), s.keysFile.ECDSA)
if err != nil {
return nil, err
}
addressBalances[i] = &pb.AddressBalances{
Address: address.String(),
Available: balances.available,
Pending: balances.pending,
Address: address.String(),
Available: balances.available,
Pending: balances.pending,
NUtxosAvailable: balances.nUtxosAvailable,
NUtxosPending: balances.nUtxosPending,
}
i++
available += balances.available
pending += balances.pending
nUtxosAvailable += balances.nUtxosAvailable
nUtxosPending += balances.nUtxosPending
}

return &pb.GetBalanceResponse{
Available: available,
Pending: pending,
NUtxosAvailable: nUtxosAvailable,
NUtxosPending: nUtxosPending,
AddressBalances: addressBalances,
}, nil
}
Expand Down
7 changes: 6 additions & 1 deletion cmd/kaspawallet/daemon/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,12 @@ func Start(params *dagconfig.Params, listen, rpcServer string, keysFilePath stri
return (errors.Wrapf(err, "Error connecting to RPC server %s", rpcServer))
}

log.Infof("Connected, reading keys file %s...", keysFilePath)
if keysFilePath == "" {
log.Infof("Connected, reading keys file...")
} else {
log.Infof("Connected, reading keys file %s...", keysFilePath)
}

keysFile, err := keys.ReadKeysFile(params, keysFilePath)
if err != nil {
return (errors.Wrapf(err, "Error reading keys file %s", keysFilePath))
Expand Down
12 changes: 11 additions & 1 deletion cmd/kaspawallet/utils/format_kas.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,21 @@ import (
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
)

// FormatKas takes the amount of sompis as uint64, and returns amount of KAS with 8 decimal places
// FormatKas takes the amount of sompis as uint64, and returns amount of KAS with 8 decimal places
func FormatKas(amount uint64) string {
res := " "
if amount > 0 {
res = fmt.Sprintf("%19.8f", float64(amount)/constants.SompiPerKaspa)
}
return res
}

// FormatUtxos takes the number of UTXOs as uint64, and returns a string
// of 8 places that is enough to express an integer up to 10^8-1
func FormatUtxos(amount uint64) string {
res := " "
if amount > 0 {
res = fmt.Sprintf("%8d", amount)
}
return res
}