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 support for auto-compound in kaspawallet send #1951

Merged
merged 42 commits into from
Mar 27, 2022
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
bcdf72b
Add GetUTXOsByBalances command to rpc
svarogg Jan 9, 2022
8444a9a
Fix wrong commands in GetBalanceByAddress
svarogg Jan 11, 2022
bccca21
Moved calculation of TransactionMass out of TransactionValidator, so …
svarogg Jan 11, 2022
504309a
Allow CreateUnsignedTransaction to return multiple transactions
svarogg Jan 29, 2022
3a91e21
Start working on split
svarogg Feb 1, 2022
d03d918
Implement maybeSplitTransactionInner
svarogg Feb 9, 2022
2be2632
estimateMassIncreaseForSignatures should multiply by the number of in…
svarogg Feb 9, 2022
6218cdb
Implement createSplitTransaction
svarogg Feb 9, 2022
c7d0267
Implement mergeTransactions
svarogg Feb 9, 2022
4abd3f1
Broadcast all transaction, not only 1
svarogg Feb 10, 2022
78b19d9
workaround missing UTXOEntry in partially signed transaction
svarogg Feb 16, 2022
529a027
Bugfix in broadcast loop
svarogg Feb 16, 2022
612726e
Add underscores in some constants
svarogg Feb 17, 2022
15369e2
Make all nets RelayNonStdTxs: false
svarogg Feb 17, 2022
135c08b
Change estimateMassIncreaseForSignatures to estimateMassAfterSignatures
svarogg Feb 17, 2022
7239bc8
Allow situations where merge transaction doesn't have enough funds to…
svarogg Feb 17, 2022
dbec7e7
Add comments
svarogg Feb 20, 2022
ee60333
A few of renames
svarogg Feb 20, 2022
3fbf8bc
Handle missed errors
svarogg Feb 20, 2022
f21e1be
Fix clone of PubKeySignaturePair to properly clone nil signatures
svarogg Feb 20, 2022
e90a374
Add sanity check to make sure originalTransaction has exactly two out…
svarogg Feb 21, 2022
84f3ecd
Re-use change address for splitAddress
svarogg Feb 22, 2022
761d461
Add one more utxo if the total amount is smaller then what we need to…
svarogg Feb 22, 2022
bbb7323
Fix off-by-1 error in splitTrasnaction
svarogg Feb 22, 2022
75f7190
Add a comment to maybeAutoCompoundTransaction
svarogg Feb 28, 2022
cb0d618
Add comment on why we are increasing inputCountPerSplit
svarogg Feb 28, 2022
7a09ed2
Add comment explaining while originalTransaction has 1 or 2 outputs
svarogg Feb 28, 2022
608bf69
Move oneMoreUTXOForMergeTransaction to split_transaction.go
svarogg Feb 28, 2022
f39bac4
Allow to add multiple utxos to pay fee for mergeTransactions, if needed
svarogg Feb 28, 2022
85accca
calculate split input counts and sizes properly
svarogg Mar 1, 2022
e4c453c
Merge remote-tracking branch 'origin/dev' into kaspwallet-auto-compou…
svarogg Mar 1, 2022
c6523bb
Allow multiple transactions inside the create-unsigned-transaction ->…
svarogg Mar 2, 2022
e3bac53
Print the number of transaction which was sent, in case there were mu…
svarogg Mar 16, 2022
c60c339
Rename broadcastConfig.Transaction(File) to Transactions(File)
svarogg Mar 16, 2022
8cc6187
Convert alreadySelectedUTXOs to a map
svarogg Mar 16, 2022
1cdc3ca
Fix a typo
svarogg Mar 16, 2022
ecf6b57
Add comment explaining that we assume all inputs are the same
svarogg Mar 21, 2022
73bfb61
Revert over-refactor of rename of config.Transaction -> config.Transa…
svarogg Mar 21, 2022
517063e
Rename: inputPerSplitCount -> inputsPerSplitCount
svarogg Mar 21, 2022
3ffacb0
Add comment for splitAndInputPerSplitCounts
svarogg Mar 21, 2022
92d9a73
Merge remote-tracking branch 'origin/dev' into kaspwallet-auto-compou…
svarogg Mar 21, 2022
88857c8
Use createSplitTransaction to calculate the upper bound of mass for s…
svarogg Mar 27, 2022
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
7 changes: 5 additions & 2 deletions cmd/kaspawallet/create_unsigned_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"encoding/hex"
"fmt"

"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/client"
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/pb"
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
Expand All @@ -20,7 +21,7 @@ func createUnsignedTransaction(conf *createUnsignedTransactionConfig) error {
defer cancel()

sendAmountSompi := uint64(conf.SendAmount * constants.SompiPerKaspa)
response, err := daemonClient.CreateUnsignedTransaction(ctx, &pb.CreateUnsignedTransactionRequest{
response, err := daemonClient.CreateUnsignedTransactions(ctx, &pb.CreateUnsignedTransactionsRequest{
Address: conf.ToAddress,
Amount: sendAmountSompi,
})
Expand All @@ -29,6 +30,8 @@ func createUnsignedTransaction(conf *createUnsignedTransactionConfig) error {
}

fmt.Println("Created unsigned transaction")
fmt.Println(hex.EncodeToString(response.UnsignedTransaction))
for _, unsignedTransaction := range response.UnsignedTransactions {
fmt.Println(hex.EncodeToString(unsignedTransaction))
}
return nil
}
193 changes: 97 additions & 96 deletions cmd/kaspawallet/daemon/pb/kaspawalletd.pb.go

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions cmd/kaspawallet/daemon/pb/kaspawalletd.proto
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ option go_package = "github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/pb";

service kaspawalletd {
rpc GetBalance (GetBalanceRequest) returns (GetBalanceResponse) {}
rpc CreateUnsignedTransaction (CreateUnsignedTransactionRequest) returns (CreateUnsignedTransactionResponse) {}
rpc CreateUnsignedTransactions (CreateUnsignedTransactionsRequest) returns (CreateUnsignedTransactionsResponse) {}
rpc ShowAddresses (ShowAddressesRequest) returns (ShowAddressesResponse) {}
rpc NewAddress (NewAddressRequest) returns (NewAddressResponse) {}
rpc Shutdown (ShutdownRequest) returns (ShutdownResponse) {}
Expand All @@ -26,13 +26,13 @@ message AddressBalances {
uint64 pending = 3;
}

message CreateUnsignedTransactionRequest {
message CreateUnsignedTransactionsRequest {
string address = 1;
uint64 amount = 2;
}

message CreateUnsignedTransactionResponse {
bytes unsignedTransaction = 1;
message CreateUnsignedTransactionsResponse {
repeated bytes unsignedTransactions = 1;
}

message ShowAddressesRequest {
Expand Down
28 changes: 14 additions & 14 deletions 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.

12 changes: 8 additions & 4 deletions cmd/kaspawallet/daemon/server/address.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ import (
"github.com/pkg/errors"
)

func (s *server) changeAddress() (util.Address, error) {
func (s *server) changeAddress() (util.Address, *walletAddress, error) {
err := s.keysFile.SetLastUsedInternalIndex(s.keysFile.LastUsedInternalIndex() + 1)
if err != nil {
return nil, err
return nil, nil, err
}

err = s.keysFile.Save()
if err != nil {
return nil, err
return nil, nil, err
}

walletAddr := &walletAddress{
Expand All @@ -27,7 +27,11 @@ func (s *server) changeAddress() (util.Address, error) {
keyChain: libkaspawallet.InternalKeychain,
}
path := s.walletAddressPath(walletAddr)
return libkaspawallet.Address(s.params, s.keysFile.ExtendedPublicKeys, s.keysFile.MinimumSignatures, path, s.keysFile.ECDSA)
address, err := libkaspawallet.Address(s.params, s.keysFile.ExtendedPublicKeys, s.keysFile.MinimumSignatures, path, s.keysFile.ECDSA)
if err != nil {
return nil, nil, err
}
return address, walletAddr, nil
}

func (s *server) ShowAddresses(_ context.Context, request *pb.ShowAddressesRequest) (*pb.ShowAddressesResponse, error) {
Expand Down
46 changes: 41 additions & 5 deletions cmd/kaspawallet/daemon/server/create_unsigned_transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ import (
"github.com/pkg/errors"
)

func (s *server) CreateUnsignedTransaction(_ context.Context, request *pb.CreateUnsignedTransactionRequest) (*pb.CreateUnsignedTransactionResponse, error) {
// TODO: Implement a better fee estimation mechanism
const feePerInput = 10000

func (s *server) CreateUnsignedTransactions(_ context.Context, request *pb.CreateUnsignedTransactionsRequest) (
*pb.CreateUnsignedTransactionsResponse, error) {
s.lock.Lock()
defer s.lock.Unlock()

Expand All @@ -28,14 +32,12 @@ func (s *server) CreateUnsignedTransaction(_ context.Context, request *pb.Create
return nil, err
}

// TODO: Implement a better fee estimation mechanism
const feePerInput = 10000
selectedUTXOs, changeSompi, err := s.selectUTXOs(request.Amount, feePerInput)
if err != nil {
return nil, err
}

changeAddress, err := s.changeAddress()
changeAddress, changeWalletAddress, err := s.changeAddress()
if err != nil {
return nil, err
}
Expand All @@ -53,7 +55,12 @@ func (s *server) CreateUnsignedTransaction(_ context.Context, request *pb.Create
return nil, err
}

return &pb.CreateUnsignedTransactionResponse{UnsignedTransaction: unsignedTransaction}, nil
unsignedTransactions, err := s.maybeAutoCompoundTransaction(unsignedTransaction, toAddress, changeAddress, changeWalletAddress)
if err != nil {
return nil, err
}

return &pb.CreateUnsignedTransactionsResponse{UnsignedTransactions: unsignedTransactions}, nil
}

func (s *server) selectUTXOs(spendAmount uint64, feePerInput uint64) (
Expand Down Expand Up @@ -95,3 +102,32 @@ func (s *server) selectUTXOs(spendAmount uint64, feePerInput uint64) (

return selectedUTXOs, totalValue - totalSpend, nil
}

func (s *server) oneMoreUTXOForMergeTransaction(alreadySelectedUTXOs []*libkaspawallet.UTXO, requiredAmount uint64) (*libkaspawallet.UTXO, error) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move this method to split_transaction.go, close to where it's used

dagInfo, err := s.rpcClient.GetBlockDAGInfo()
if err != nil {
return nil, err
}

var utxo *walletUTXO
for _, utxo = range s.utxosSortedByAmount {
if !isUTXOSpendable(utxo, dagInfo.VirtualDAAScore, s.params.BlockCoinbaseMaturity) {
continue
}
if utxo.UTXOEntry.Amount() < requiredAmount+feePerInput {
return nil, errors.Errorf("Insufficient funds for merge transaction")
}
for _, alreadySelectedUTXO := range alreadySelectedUTXOs {
someone235 marked this conversation as resolved.
Show resolved Hide resolved
if alreadySelectedUTXO.Outpoint.Equal(utxo.Outpoint) {
// comparing outpoints should be sufficient as they are unique per utxo entry
continue
}
}
break
}
return &libkaspawallet.UTXO{
Outpoint: utxo.Outpoint,
UTXOEntry: utxo.UTXOEntry,
DerivationPath: s.walletAddressPath(utxo.address),
}, nil
}
4 changes: 4 additions & 0 deletions cmd/kaspawallet/daemon/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"sync"
"time"

"github.com/kaspanet/kaspad/util/txmass"

"github.com/kaspanet/kaspad/util/profiling"

"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/pb"
Expand All @@ -32,6 +34,7 @@ type server struct {
keysFile *keys.File
shutdown chan struct{}
addressSet walletAddressSet
txMassCalculator *txmass.Calculator
}

// Start starts the kaspawalletd server
Expand Down Expand Up @@ -69,6 +72,7 @@ func Start(params *dagconfig.Params, listen, rpcServer string, keysFilePath stri
keysFile: keysFile,
shutdown: make(chan struct{}),
addressSet: make(walletAddressSet),
txMassCalculator: txmass.NewCalculator(params.MassPerTxByte, params.MassPerScriptPubKeyByte, params.MassPerSigOp),
}

spawn("serverInstance.sync", func() {
Expand Down
Loading