[client] Improve coinselection & verbosity (#104)

* cli logs + handle dust amount

* add wallet initialized

* Update client/common.go

Co-authored-by: Pietralberto Mazza <18440657+altafan@users.noreply.github.com>
Signed-off-by: Louis Singer <41042567+louisinger@users.noreply.github.com>

---------

Signed-off-by: Louis Singer <41042567+louisinger@users.noreply.github.com>
Co-authored-by: Pietralberto Mazza <18440657+altafan@users.noreply.github.com>
This commit is contained in:
Louis Singer
2024-02-12 18:02:09 +01:00
committed by GitHub
parent 7778b6b5a1
commit 9944a3cc48
3 changed files with 30 additions and 10 deletions

View File

@@ -26,6 +26,10 @@ import (
"golang.org/x/term" "golang.org/x/term"
) )
const (
DUST = 450
)
func hashPassword(password []byte) []byte { func hashPassword(password []byte) []byte {
hash := sha256.Sum256(password) hash := sha256.Sum256(password)
return hash[:] return hash[:]
@@ -57,15 +61,14 @@ func verifyPassword(password []byte) error {
} }
func readPassword() ([]byte, error) { func readPassword() ([]byte, error) {
fmt.Print("password: ") fmt.Print("unlock your wallet with password: ")
passwordInput, err := term.ReadPassword(int(syscall.Stdin)) passwordInput, err := term.ReadPassword(int(syscall.Stdin))
fmt.Println() // new line fmt.Println() // new line
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = verifyPassword(passwordInput) if err := verifyPassword(passwordInput); err != nil {
if err != nil {
return nil, err return nil, err
} }
@@ -92,7 +95,7 @@ func privateKeyFromPassword() (*secp256k1.PrivateKey, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
fmt.Println("key unlocked") fmt.Println("wallet unlocked")
cypher := NewAES128Cypher() cypher := NewAES128Cypher()
privateKeyBytes, err := cypher.Decrypt(encryptedPrivateKey, password) privateKeyBytes, err := cypher.Decrypt(encryptedPrivateKey, password)
@@ -144,10 +147,12 @@ func getServiceProviderPublicKey() (*secp256k1.PublicKey, error) {
func coinSelect(vtxos []vtxo, amount uint64) ([]vtxo, uint64, error) { func coinSelect(vtxos []vtxo, amount uint64) ([]vtxo, uint64, error) {
selected := make([]vtxo, 0) selected := make([]vtxo, 0)
notSelected := make([]vtxo, 0)
selectedAmount := uint64(0) selectedAmount := uint64(0)
for _, vtxo := range vtxos { for _, vtxo := range vtxos {
if selectedAmount >= amount { if selectedAmount >= amount {
notSelected = append(notSelected, vtxo)
break break
} }
@@ -161,6 +166,13 @@ func coinSelect(vtxos []vtxo, amount uint64) ([]vtxo, uint64, error) {
change := selectedAmount - amount change := selectedAmount - amount
if change < DUST {
if len(notSelected) > 0 {
selected = append(selected, notSelected[0])
change += notSelected[0].amount
}
}
return selected, change, nil return selected, change, nil
} }
@@ -500,7 +512,7 @@ func handleRoundStream(
forfeits := event.GetRoundFinalization().GetForfeitTxs() forfeits := event.GetRoundFinalization().GetForfeitTxs()
signedForfeits := make([]string, 0) signedForfeits := make([]string, 0)
fmt.Println("signing forfeit txs...") fmt.Print("signing forfeit txs... ")
explorer := NewExplorer() explorer := NewExplorer()
@@ -533,7 +545,7 @@ func handleRoundStream(
// if no forfeit txs have been signed, start pinging again and wait for the next round // if no forfeit txs have been signed, start pinging again and wait for the next round
if len(signedForfeits) == 0 { if len(signedForfeits) == 0 {
fmt.Println("no forfeit txs to sign, waiting for the next round...") fmt.Printf("\nno forfeit txs to sign, waiting for the next round...\n")
pingStop = nil pingStop = nil
for pingStop == nil { for pingStop == nil {
pingStop = ping(ctx, client, pingReq) pingStop = ping(ctx, client, pingReq)
@@ -541,13 +553,16 @@ func handleRoundStream(
continue continue
} }
fmt.Printf("%d forfeit txs signed, finalizing payment...\n", len(signedForfeits)) fmt.Printf("%d signed\n", len(signedForfeits))
fmt.Print("finalizing payment... ")
_, err = client.FinalizePayment(ctx.Context, &arkv1.FinalizePaymentRequest{ _, err = client.FinalizePayment(ctx.Context, &arkv1.FinalizePaymentRequest{
SignedForfeitTxs: signedForfeits, SignedForfeitTxs: signedForfeits,
}) })
if err != nil { if err != nil {
return "", err return "", err
} }
fmt.Print("done.\n")
fmt.Println("waiting for round finalization...")
continue continue
} }

View File

@@ -133,5 +133,10 @@ func initWallet(ctx *cli.Context, key, password string) error {
"public_key": publicKey, "public_key": publicKey,
} }
return setState(state) if err := setState(state); err != nil {
return err
}
fmt.Println("wallet initialized")
return nil
} }

View File

@@ -86,8 +86,8 @@ func sendAction(ctx *cli.Context) error {
return fmt.Errorf("invalid receiver address '%s': must be associated with the connected service provider", receiver.To) return fmt.Errorf("invalid receiver address '%s': must be associated with the connected service provider", receiver.To)
} }
if receiver.Amount <= 0 { if receiver.Amount < DUST {
return fmt.Errorf("invalid amount: %d", receiver.Amount) return fmt.Errorf("invalid amount (%d), must be greater than dust %d", receiver.Amount, DUST)
} }
receiversOutput = append(receiversOutput, &arkv1.Output{ receiversOutput = append(receiversOutput, &arkv1.Output{