Skip to content

Commit 1a4211d

Browse files
akbariandevmj
andauthored
fix(voucher): check validator existance on claim (#159)
Co-authored-by: mj <akbarian.dev@gmail.ccom>
1 parent 7cef761 commit 1a4211d

File tree

7 files changed

+129
-13
lines changed

7 files changed

+129
-13
lines changed

internal/engine/command/voucher/claim.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package voucher
22

33
import (
44
"errors"
5+
"fmt"
56
"time"
67

78
"github.com/pagu-project/Pagu/internal/engine/command"
@@ -34,14 +35,21 @@ func (v *Voucher) claimHandler(
3435
}
3536

3637
address := args["address"]
37-
validatorInfo, err := v.clientManager.GetValidatorInfo(address)
38+
valInfo, _ := v.clientManager.GetValidatorInfo(address)
39+
if valInfo.Validator != nil {
40+
err = errors.New("this address is already a staked validator")
41+
log.Warn(fmt.Sprintf("staked validator found. %s", address))
42+
return cmd.ErrorResult(err)
43+
}
44+
45+
pubKey, err := v.clientManager.FindPublicKey(address, false)
3846
if err != nil {
39-
log.Error("error get validator info", "err", err)
47+
log.Warn(fmt.Sprintf("peer not found. %s", address))
4048
return cmd.ErrorResult(err)
4149
}
4250

43-
pubKey := validatorInfo.GetValidator().GetPublicKey()
44-
txHash, err := v.wallet.BondTransaction(pubKey, address, "Voucher claim from Pagu", voucher.Amount)
51+
memo := fmt.Sprintf("voucher %s claimed by Pagu", code)
52+
txHash, err := v.wallet.BondTransaction(pubKey, address, memo, voucher.Amount)
4553
if err != nil {
4654
return cmd.ErrorResult(err)
4755
}

internal/engine/command/voucher/claim_test.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package voucher
22

33
import (
44
"errors"
5+
"fmt"
6+
"math/rand"
57
"testing"
68

79
pactus "github.com/pactus-project/pactus/www/grpc/gen/go"
@@ -14,6 +16,7 @@ import (
1416
func TestClaimNormal(t *testing.T) {
1517
voucher, db, client, wallet := setup(t)
1618

19+
validatorAddr := fmt.Sprintf("pc1z%d", rand.Intn(1000000)) //nolint
1720
t.Run("normal", func(t *testing.T) {
1821
amt, _ := amount.NewAmount(100)
1922
db.EXPECT().GetVoucherByCode("12345678").Return(
@@ -24,15 +27,17 @@ func TestClaimNormal(t *testing.T) {
2427
}, nil,
2528
).AnyTimes()
2629

27-
client.EXPECT().GetValidatorInfo("pc1z").Return(
30+
client.EXPECT().GetValidatorInfo(validatorAddr).Return(
2831
&pactus.GetValidatorResponse{
29-
Validator: &pactus.ValidatorInfo{
30-
PublicKey: "pc1z",
31-
},
32+
Validator: nil,
3233
}, nil,
3334
).AnyTimes()
3435

35-
wallet.EXPECT().BondTransaction("pc1z", "pc1z", "Voucher claim from Pagu", amt).Return(
36+
client.EXPECT().FindPublicKey(validatorAddr, false).Return(
37+
validatorAddr, nil,
38+
).AnyTimes()
39+
40+
wallet.EXPECT().BondTransaction(validatorAddr, validatorAddr, "voucher 12345678 claimed by Pagu", amt).Return(
3641
"0x1", nil,
3742
).AnyTimes()
3843

@@ -45,7 +50,7 @@ func TestClaimNormal(t *testing.T) {
4550

4651
args := make(map[string]string)
4752
args["code"] = "12345678"
48-
args["address"] = "pc1z"
53+
args["address"] = validatorAddr
4954
result := voucher.claimHandler(caller, cmd, args)
5055
assert.True(t, result.Successful)
5156
assert.Equal(t, result.Message, "Voucher claimed successfully!\n\n https://pacviewer.com/transaction/0x1")

internal/engine/command/wallet.middleware.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
package command
22

33
import (
4-
"errors"
4+
"fmt"
55

66
"github.com/pagu-project/Pagu/internal/entity"
77
)
88

9+
const minWalletBalance = 500
10+
911
func (h *MiddlewareHandler) WalletBalance(_ *entity.User, _ *Command, _ map[string]string) error {
10-
if h.wallet.Balance() < 5 {
11-
return errors.New("the Pagu Wallet balance is less than 5 PAC")
12+
if h.wallet.Balance() < minWalletBalance {
13+
return fmt.Errorf("the Pagu Wallet balance is less than %d PAC", minWalletBalance)
1214
}
1315

1416
return nil

pkg/client/client_mgr.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package client
22

33
import (
44
"context"
5+
"errors"
56
"fmt"
67
"sync"
78
"time"
@@ -134,6 +135,7 @@ func (cm *Mgr) GetLastBlockTime() (lastBlockTime, lastBlockHeight uint32) {
134135
}
135136

136137
func (cm *Mgr) GetNetworkInfo() (*pactus.GetNetworkInfoResponse, error) {
138+
// TODO: use caching and object
137139
for _, c := range cm.clients {
138140
info, err := c.GetNetworkInfo(cm.ctx)
139141
if err != nil {
@@ -248,3 +250,21 @@ func (cm *Mgr) GetCirculatingSupply() (int64, error) {
248250
circulating := (addr1Out + addr2Out + addr3Out + addr4Out + addr5Out + addr6Out + int64(minted)) - staked - warm
249251
return circulating, nil
250252
}
253+
254+
func (cm *Mgr) FindPublicKey(address string, firstVal bool) (string, error) { //nolint
255+
peerInfo, err := cm.GetPeerInfo(address)
256+
if err != nil {
257+
return "", err
258+
}
259+
260+
for i, addr := range peerInfo.ConsensusAddresses {
261+
if addr == address {
262+
if firstVal && i != 0 {
263+
return "", errors.New("please enter the first validator address")
264+
}
265+
return peerInfo.ConsensusKeys[i], nil
266+
}
267+
}
268+
269+
panic("unreachable")
270+
}

pkg/client/client_mgr_test.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package client
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
pactus "github.com/pactus-project/pactus/www/grpc/gen/go"
8+
"github.com/stretchr/testify/assert"
9+
"go.uber.org/mock/gomock"
10+
)
11+
12+
func setup(t *testing.T) (Manager, *MockIClient) {
13+
t.Helper()
14+
ctrl := gomock.NewController(t)
15+
mockClient := NewMockIClient(ctrl)
16+
17+
clientMgr := NewClientMgr(context.Background())
18+
clientMgr.AddClient(mockClient)
19+
20+
return clientMgr, mockClient
21+
}
22+
23+
func TestFindPublicKey(t *testing.T) {
24+
clientMgr, mockClient := setup(t)
25+
26+
mockClient.EXPECT().GetNetworkInfo(gomock.Any()).Return(
27+
&pactus.GetNetworkInfoResponse{
28+
ConnectedPeers: []*pactus.PeerInfo{
29+
{
30+
ConsensusKeys: []string{"pubKey-1", "pubKey-2"},
31+
ConsensusAddresses: []string{"addr-1", "addr-2"},
32+
},
33+
{
34+
ConsensusKeys: []string{"pubKey-3", "pubKey-4"},
35+
ConsensusAddresses: []string{"addr-3", "addr-4"},
36+
},
37+
},
38+
}, nil,
39+
).AnyTimes()
40+
41+
clientMgr.updateValMap()
42+
t.Run("not found", func(t *testing.T) {
43+
pubKey, err := clientMgr.FindPublicKey("not-exists", false)
44+
assert.Error(t, err)
45+
assert.Empty(t, pubKey)
46+
})
47+
48+
t.Run("not first", func(t *testing.T) {
49+
pubKey, err := clientMgr.FindPublicKey("addr-4", true)
50+
assert.Error(t, err)
51+
assert.Empty(t, pubKey)
52+
})
53+
54+
t.Run("first-ok", func(t *testing.T) {
55+
pubKey, err := clientMgr.FindPublicKey("addr-3", true)
56+
assert.NoError(t, err)
57+
assert.Equal(t, pubKey, "pubKey-3")
58+
})
59+
60+
t.Run("any-ok", func(t *testing.T) {
61+
pubKey, err := clientMgr.FindPublicKey("addr-4", false)
62+
assert.NoError(t, err)
63+
assert.Equal(t, pubKey, "pubKey-4")
64+
})
65+
}

pkg/client/interface.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,5 @@ type Manager interface {
3737
GetBalance(addr string) (int64, error)
3838
GetFee(amt int64) (int64, error)
3939
GetCirculatingSupply() (int64, error)
40+
FindPublicKey(address string, firstVal bool) (string, error)
4041
}

pkg/client/mock.go

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)