Skip to content

Commit

Permalink
fix transfer err
Browse files Browse the repository at this point in the history
  • Loading branch information
bxy4543 committed Jul 3, 2023
1 parent d4c13bd commit b979ae1
Show file tree
Hide file tree
Showing 3 changed files with 181 additions and 48 deletions.
51 changes: 25 additions & 26 deletions controllers/account/controllers/account_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,10 @@ func (r *AccountReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct

accountBalance := accountv1.AccountBalance{}
if err := r.Get(ctx, req.NamespacedName, &accountBalance); err == nil {
if err := r.updateDeductionBalance(ctx, &accountBalance); err != nil {
r.Logger.Error(err, err.Error())
err = retry2.RetryOnConflict(retry2.DefaultBackoff, func() error {
return r.updateDeductionBalance(ctx, &accountBalance)
})
if err != nil {
return ctrl.Result{}, err
}
} else if client.IgnoreNotFound(err) != nil {
Expand Down Expand Up @@ -151,12 +153,11 @@ func (r *AccountReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
now := time.Now().UTC()
payAmount := *orderResp.Amount.Total * 10000
//1¥ = 100WechatPayAmount; 1 WechatPayAmount = 10000 SealosAmount
account.Status.Balance += giveGift(payAmount)
account.Status.EncryptBalance, err = crypto.EncryptInt64(account.Status.Balance)
account.Status.EncryptBalance, err = crypto.RechargeBalance(account.Status.EncryptBalance, giveGift(payAmount))
if err != nil {
return ctrl.Result{}, fmt.Errorf("recharge encrypt balance failed: %v", err)
}
if err := r.Status().Update(ctx, account); err != nil {
if err := r.updateAccountStatus(ctx, account); err != nil {
return ctrl.Result{}, fmt.Errorf("update account failed: %v", err)
}
payment.Status.Status = pay.StatusSuccess
Expand Down Expand Up @@ -242,9 +243,8 @@ func (r *AccountReconciler) syncAccount(ctx context.Context, name, accountNamesp
if err != nil {
return nil, fmt.Errorf("recharge balance failed: %v", err)
}
account.Status.Balance += int64(amount)
if err := r.Status().Update(ctx, &account); err != nil {
return nil, err
if err := r.updateAccountStatus(ctx, &account); err != nil {
return nil, fmt.Errorf("update account failed: %v", err)
}
r.Logger.Info("account created,will charge new account some money", "account", account, "stringAmount", stringAmount)

Expand Down Expand Up @@ -355,28 +355,25 @@ func (r *AccountReconciler) updateDeductionBalance(ctx context.Context, accountB
r.Logger.Error(err, err.Error())
return err
}
/*sync*/
err = r.syncBalance(account)
///*sync*/
err = r.initBalance(account)
if err != nil {
return fmt.Errorf("sync balance failed: %v", err)
}
switch accountBalance.Spec.Type {
case accountv1.TransferIn:
account.Status.Balance += accountBalance.Spec.Amount
account.Status.EncryptBalance, err = crypto.RechargeBalance(account.Status.EncryptBalance, accountBalance.Spec.Amount)
if err != nil {
r.Logger.Error(err, err.Error())
return err
}
case accountv1.TransferOut:
account.Status.Balance -= accountBalance.Spec.Amount
account.Status.EncryptBalance, err = crypto.RechargeBalance(account.Status.EncryptBalance, accountBalance.Spec.Amount)
account.Status.EncryptBalance, err = crypto.DeductBalance(account.Status.EncryptBalance, accountBalance.Spec.Amount)
if err != nil {
r.Logger.Error(err, err.Error())
return err
}
case accountv1.Consumption:
account.Status.DeductionBalance += accountBalance.Spec.Amount
account.Status.EncryptDeductionBalance, err = crypto.RechargeBalance(account.Status.EncryptDeductionBalance, accountBalance.Spec.Amount)
if err != nil {
r.Logger.Error(err, err.Error())
Expand All @@ -386,7 +383,7 @@ func (r *AccountReconciler) updateDeductionBalance(ctx context.Context, accountB
return fmt.Errorf("unknown accountbalance type: %v", accountBalance.Spec.Type)
}

if err := r.Status().Update(ctx, account); err != nil {
if err := r.updateAccountStatus(ctx, account); err != nil {
r.Logger.Error(err, err.Error())
return err
}
Expand Down Expand Up @@ -415,28 +412,30 @@ func (r *AccountReconciler) updateDeductionBalance(ctx context.Context, accountB
return nil
}

func (r *AccountReconciler) syncBalance(account *accountv1.Account) (err error) {
func (r *AccountReconciler) updateAccountStatus(ctx context.Context, account *accountv1.Account) (err error) {
account.Status.Balance, err = crypto.DecryptInt64(*account.Status.EncryptBalance)
if err != nil {
return fmt.Errorf("update decrypt balance failed: %v", err)
}
account.Status.DeductionBalance, err = crypto.DecryptInt64(*account.Status.EncryptDeductionBalance)
if err != nil {
return fmt.Errorf("update decrypt deduction balance failed: %v", err)
}
return r.Status().Update(ctx, account)
}

func (r *AccountReconciler) initBalance(account *accountv1.Account) (err error) {
if account.Status.EncryptBalance == nil {
account.Status.EncryptBalance, err = crypto.EncryptInt64(account.Status.Balance)
if err != nil {
return fmt.Errorf("sync encrypt balance failed: %v", err)
}
} else {
account.Status.Balance, err = crypto.DecryptInt64(*account.Status.EncryptBalance)
if err != nil {
return fmt.Errorf("sync decrypt balance failed: %v", err)
}
}
if account.Status.EncryptDeductionBalance == nil {
account.Status.EncryptDeductionBalance, err = crypto.EncryptInt64(account.Status.DeductionBalance)
if err != nil {
return fmt.Errorf("sync encrypt deduction balance failed: %v", err)
}
} else {
account.Status.DeductionBalance, err = crypto.DecryptInt64(*account.Status.EncryptDeductionBalance)
if err != nil {
return fmt.Errorf("sync decrypt deduction balance failed: %v", err)
}
}
return nil
}
Expand Down
53 changes: 31 additions & 22 deletions controllers/pkg/crypto/crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,28 +52,6 @@ func Encrypt(plaintext []byte) (string, error) {
return base64.StdEncoding.EncodeToString(append(nonce, ciphertext...)), nil
}

func EncryptInt64(in int64) (*string, error) {
out, err := Encrypt([]byte(strconv.FormatInt(in, 10)))
return &out, err
}

func DecryptInt64(in string) (int64, error) {
out, err := Decrypt(in)
if err != nil {
return 0, fmt.Errorf("failed to decrpt balance: %w", err)
}
return strconv.ParseInt(string(out), 10, 64)
}

func RechargeBalance(balance *string, amount int64) (*string, error) {
balanceInt, err := DecryptInt64(*balance)
if err != nil {
return nil, fmt.Errorf("failed to recharge balance: %w", err)
}
balanceInt += amount
return EncryptInt64(balanceInt)
}

// Decrypt decrypts the given ciphertext using AES-GCM.
func Decrypt(ciphertextBase64 string) ([]byte, error) {
ciphertext, err := base64.StdEncoding.DecodeString(ciphertextBase64)
Expand Down Expand Up @@ -105,6 +83,37 @@ func Decrypt(ciphertextBase64 string) ([]byte, error) {
return plaintext, nil
}

func EncryptInt64(in int64) (*string, error) {
out, err := Encrypt([]byte(strconv.FormatInt(in, 10)))
return &out, err
}

func DecryptInt64(in string) (int64, error) {
out, err := Decrypt(in)
if err != nil {
return 0, fmt.Errorf("failed to decrpt balance: %w", err)
}
return strconv.ParseInt(string(out), 10, 64)
}

func RechargeBalance(balance *string, amount int64) (*string, error) {
balanceInt, err := DecryptInt64(*balance)
if err != nil {
return nil, fmt.Errorf("failed to recharge balance: %w", err)
}
balanceInt += amount
return EncryptInt64(balanceInt)
}

func DeductBalance(balance *string, amount int64) (*string, error) {
balanceInt, err := DecryptInt64(*balance)
if err != nil {
return nil, fmt.Errorf("failed to deduct balance: %w", err)
}
balanceInt -= amount
return EncryptInt64(balanceInt)
}

//func IsLicenseValid(license v1.License) (map[string]interface{}, bool) {
// publicKey, err := parseRSAPublicKeyFromPEM(license.Spec.Key)
// if err != nil {
Expand Down
125 changes: 125 additions & 0 deletions controllers/pkg/crypto/crypto_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package crypto

import (
"math/rand"
"reflect"
"testing"
)

func TestEncryptDecryptInt64(t *testing.T) {
type testCase struct {
name string
input int64
wantErr bool
}

// Generate a random int64 value greater than 1000000
randomInt64 := rand.Int63n(900000000000000) + 1000000

tests := []testCase{
{
name: "Positive value",
input: 1234567000000,
wantErr: false,
},
{
name: "Negative value",
input: 666666000000,
wantErr: false,
},
{
name: "Zero value",
input: 0,
wantErr: false,
},
{
name: "Large positive value",
input: 9223372036854775807,
wantErr: false,
},
{
name: "Large negative value",
input: 9223372036854775807,
wantErr: false,
},
{
name: "Random value",
input: randomInt64,
wantErr: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Encrypt the int64 value
encryptedValue, err := EncryptInt64(tt.input)
if (err != nil) != tt.wantErr {
t.Errorf("EncryptInt64() error = %v, wantErr %v", err, tt.wantErr)
return
}

// Decrypt the encrypted value
decryptedValue, err := DecryptInt64(*encryptedValue)
if (err != nil) != tt.wantErr {
t.Errorf("DecryptInt64() error = %v, wantErr %v", err, tt.wantErr)
return
}

// Compare the decrypted value with the original value
if tt.input != decryptedValue {
t.Errorf("Decrypted value does not match the original value: expected %d, got %d", tt.input, decryptedValue)
}
})
}
}

func TestRechargeBalance(t *testing.T) {
type args struct {
balance *string
amount int64
}
tests := []struct {
name string
args args
want *string
wantErr bool
}{
{
name: "Positive amount",
args: args{
balance: newString("1000000"),
amount: 500000,
},
want: newString("1500000"),
wantErr: false,
},
{
name: "Zero amount",
args: args{
balance: newString("1000"),
amount: 0,
},
want: newString("1000"),
wantErr: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

got, err := RechargeBalance(tt.args.balance, tt.args.amount)
if (err != nil) != tt.wantErr {
t.Errorf("RechargeBalance() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("RechargeBalance() got = %v, want %v", got, tt.want)
}
})
}
}

// Helper function to create a new string pointer
func newString(s string) *string {
return &s
}

0 comments on commit b979ae1

Please sign in to comment.