Skip to content

Commit 0a76db9

Browse files
committed
fix de
1 parent dfd3c0b commit 0a76db9

File tree

17 files changed

+294
-648
lines changed

17 files changed

+294
-648
lines changed

cylinder/store/store.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,11 @@ func (s *Store) GetDE(pubDE types.DE) (DE, error) {
184184
return de, err
185185
}
186186

187+
func (s *Store) HasDE(pubDE types.DE) bool {
188+
bytes, err := s.DB.Get(DEStoreKey(pubDE))
189+
return err == nil && bytes != nil
190+
}
191+
187192
// DeleteDE deletes the private (d, E) by the given public (D, E)
188193
func (s *Store) DeleteDE(pubDE types.DE) error {
189194
return s.DB.DeleteSync(DEStoreKey(pubDE))

cylinder/workers/de/de.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,11 @@ func (de *DE) updateDE() {
121121
de.logger.Info(":delivery_truck: Updating DE")
122122

123123
// Generate new DE pairs
124-
privDEs, err := GenerateDEs(de.context.Config.MinDE, de.context.Config.RandomSecret)
124+
privDEs, err := GenerateDEs(
125+
de.context.Config.MinDE,
126+
de.context.Config.RandomSecret,
127+
de.context.Store,
128+
)
125129
if err != nil {
126130
de.logger.Error(":cold_sweat: Failed to generate new DE pairs: %s", err)
127131
return

cylinder/workers/de/helpers.go

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,27 @@
11
package de
22

33
import (
4+
"errors"
5+
46
"github.com/bandprotocol/chain/v2/cylinder/store"
57
"github.com/bandprotocol/chain/v2/pkg/tss"
68
"github.com/bandprotocol/chain/v2/x/tss/types"
79
)
810

11+
const (
12+
MaxDuplicateDEAttempts = 5
13+
)
14+
15+
type DEGetter interface {
16+
HasDE(de types.DE) bool
17+
}
18+
919
// GenerateDEs generates n pairs of DE by using secret value as a random factor
10-
func GenerateDEs(n uint64, secret tss.Scalar) (privDEs []store.DE, err error) {
11-
for i := uint64(1); i <= n; i++ {
20+
func GenerateDEs(n uint64, secret tss.Scalar, db DEGetter) (privDEs []store.DE, err error) {
21+
privDEs = make([]store.DE, 0, n)
22+
attempt := 0
23+
24+
for len(privDEs) < int(n) && attempt < MaxDuplicateDEAttempts {
1225
privD, err := tss.GenerateSigningNonce(secret)
1326
if err != nil {
1427
return nil, err
@@ -19,15 +32,27 @@ func GenerateDEs(n uint64, secret tss.Scalar) (privDEs []store.DE, err error) {
1932
return nil, err
2033
}
2134

35+
pubDE := types.DE{
36+
PubD: privD.Point(),
37+
PubE: privE.Point(),
38+
}
39+
40+
if db.HasDE(pubDE) {
41+
attempt += 1
42+
continue
43+
}
44+
2245
privDEs = append(privDEs, store.DE{
23-
PubDE: types.DE{
24-
PubD: privD.Point(),
25-
PubE: privE.Point(),
26-
},
46+
PubDE: pubDE,
2747
PrivD: privD,
2848
PrivE: privE,
2949
})
3050
}
3151

52+
// Unlikely to occur, but included for fail-safe measures.
53+
if attempt >= MaxDuplicateDEAttempts {
54+
return nil, errors.New("reach maximum generating duplicated DE")
55+
}
56+
3257
return privDEs, nil
3358
}

cylinder/workers/de/helpers_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,15 @@ import (
66
"github.com/stretchr/testify/assert"
77

88
"github.com/bandprotocol/chain/v2/cylinder/workers/de"
9+
"github.com/bandprotocol/chain/v2/x/tss/types"
910
)
1011

12+
type MockDEGetter struct{}
13+
14+
func (m *MockDEGetter) HasDE(de types.DE) bool { return false }
15+
1116
func TestGenerateDEs(t *testing.T) {
12-
privDEs, err := de.GenerateDEs(10, []byte("secret"))
17+
privDEs, err := de.GenerateDEs(10, []byte("secret"), &MockDEGetter{})
1318
assert.NoError(t, err)
1419

1520
for _, privDE := range privDEs {

proto/tss/v1beta1/tss.proto

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,6 @@ message DE {
5959
bytes pub_e = 2 [(gogoproto.casttype) = "github.com/bandprotocol/chain/v2/pkg/tss.Point"];
6060
}
6161

62-
// DEQueue is a simple queue data structure for holding DE objects.
63-
message DEQueue {
64-
// address is the address of the de holder.
65-
string address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
66-
// head is the index of the first element in the queue.
67-
uint64 head = 2;
68-
// tail is the index of the last element in the queue.
69-
uint64 tail = 3;
70-
}
71-
7262
// Signing contains all necessary information for handling a signing request.
7363
message Signing {
7464
// id is the unique identifier of the signing.

x/bandtss/keeper/keeper_test.go

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -155,14 +155,19 @@ func (s *KeeperTestSuite) setupDE() {
155155
for _, tc := range testutil.TestCases {
156156
for _, m := range tc.Group.Members {
157157
// Submit DEs for each member
158+
des := make([]tsstypes.DE, 0, 5)
159+
for i := 0; i < 5; i++ {
160+
privD, err := tss.GenerateSigningNonce(m.PrivKey)
161+
s.Require().NoError(err)
162+
163+
privE, err := tss.GenerateSigningNonce(m.PrivKey)
164+
s.Require().NoError(err)
165+
166+
des = append(des, tsstypes.DE{PubD: privD.Point(), PubE: privE.Point()})
167+
}
168+
158169
_, err := tssMsgSrvr.SubmitDEs(ctx, &tsstypes.MsgSubmitDEs{
159-
DEs: []tsstypes.DE{
160-
{PubD: PubD, PubE: PubE},
161-
{PubD: PubD, PubE: PubE},
162-
{PubD: PubD, PubE: PubE},
163-
{PubD: PubD, PubE: PubE},
164-
{PubD: PubD, PubE: PubE},
165-
},
170+
DEs: des,
166171
Address: sdk.AccAddress(m.PubKey()).String(),
167172
})
168173
s.Require().NoError(err)

x/tss/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ var (
100100
ConfirmComplainCountStoreKeyPrefix = []byte{0x0a}
101101
ConfirmStoreKeyPrefix = []byte{0x0b}
102102
DEStoreKeyPrefix = []byte{0x0c}
103-
DEQueueStoreKeyPrefix = []byte{0x0d}
103+
DECountStoreKeyPrefix = []byte{0x0d}
104104
SigningStoreKeyPrefix = []byte{0x0e}
105105
PartialSignatureCountStoreKeyPrefix = []byte{0x0f}
106106
PartialSignatureStoreKeyPrefix = []byte{0x10}

x/tss/genesis.go

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,11 @@ func InitGenesis(ctx sdk.Context, k *keeper.Keeper, data *types.GenesisState) {
3737
panic(fmt.Sprintf("DEsGenesis of %s size exceeds MaxDESize", addr))
3838
}
3939

40-
k.SetDEQueue(ctx, types.DEQueue{
41-
Address: addr,
42-
Head: 0,
43-
Tail: uint64(len(des)),
44-
})
45-
4640
acc := sdk.MustAccAddressFromBech32(addr)
47-
for i, de := range des {
48-
k.SetDE(ctx, acc, uint64(i), de)
41+
k.SetDECount(ctx, acc, uint64(len(des)))
42+
43+
for _, de := range des {
44+
k.SetDE(ctx, acc, de)
4945
}
5046
}
5147
}

x/tss/genesis_test.go

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,6 @@ func TestExportGenesis(t *testing.T) {
8989
require.Equal(t, data.DEsGenesis, exported.DEsGenesis)
9090

9191
require.Equal(t, uint64(2), k.GetDECount(ctx, addr1))
92-
de, err := k.GetDE(ctx, addr1, 1)
93-
require.NoError(t, err)
94-
require.Equal(
95-
t,
96-
types.DE{
97-
PubD: []byte("pubD2"),
98-
PubE: []byte("pubE2"),
99-
},
100-
de,
101-
)
92+
hasDE := k.HasDE(ctx, addr1, types.DE{PubD: []byte("pubD2"), PubE: []byte("pubE2")})
93+
require.True(t, hasDE)
10294
}

x/tss/keeper/de.go

Lines changed: 46 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,54 @@
11
package keeper
22

33
import (
4-
"fmt"
5-
64
sdk "github.com/cosmos/cosmos-sdk/types"
75
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
86

97
"github.com/bandprotocol/chain/v2/x/tss/types"
108
)
119

12-
// SetDEQueue sets the DEQueue for a given address in the context's KVStore.
13-
func (k Keeper) SetDEQueue(ctx sdk.Context, deQueue types.DEQueue) {
14-
address := sdk.MustAccAddressFromBech32(deQueue.Address)
15-
ctx.KVStore(k.storeKey).Set(types.DEQueueKeyStoreKey(address), k.cdc.MustMarshal(&deQueue))
10+
// SetDECount sets the number of existing DE for a given address.
11+
func (k Keeper) SetDECount(ctx sdk.Context, address sdk.AccAddress, count uint64) {
12+
ctx.KVStore(k.storeKey).Set(types.DECountStoreKey(address), sdk.Uint64ToBigEndian(count))
1613
}
1714

18-
// GetDEQueue retrieves the DEQueue for a given address from the context's KVStore.
19-
func (k Keeper) GetDEQueue(ctx sdk.Context, address sdk.AccAddress) types.DEQueue {
20-
bz := ctx.KVStore(k.storeKey).Get(types.DEQueueKeyStoreKey(address))
21-
if bz == nil {
22-
return types.DEQueue{
23-
Address: address.String(),
24-
Head: 0,
25-
Tail: 0,
26-
}
27-
}
28-
var deQueue types.DEQueue
29-
k.cdc.MustUnmarshal(bz, &deQueue)
30-
return deQueue
15+
// GetDECount retrieves the number of existing DE for a given address.
16+
func (k Keeper) GetDECount(ctx sdk.Context, address sdk.AccAddress) uint64 {
17+
return sdk.BigEndianToUint64(ctx.KVStore(k.storeKey).Get(types.DECountStoreKey(address)))
3118
}
3219

33-
// GetDEQueueIterator function gets an iterator over all de queue from the context's KVStore.
34-
func (k Keeper) GetDEQueueIterator(ctx sdk.Context) sdk.Iterator {
35-
return sdk.KVStorePrefixIterator(ctx.KVStore(k.storeKey), types.DEQueueStoreKeyPrefix)
20+
// GetDEByAddressIterator function gets an iterator over the DEs of the given address.
21+
func (k Keeper) GetDEByAddressIterator(ctx sdk.Context, addr sdk.AccAddress) sdk.Iterator {
22+
return sdk.KVStorePrefixIterator(ctx.KVStore(k.storeKey), types.DEStoreKeyPerAddressPrefix(addr))
3623
}
3724

38-
// GetDEQueues retrieves all DEQueues from the context's KVStore.
39-
func (k Keeper) GetDEQueues(ctx sdk.Context) []types.DEQueue {
40-
var deQueues []types.DEQueue
41-
iterator := k.GetDEQueueIterator(ctx)
42-
defer iterator.Close()
43-
for ; iterator.Valid(); iterator.Next() {
44-
var deQueue types.DEQueue
45-
k.cdc.MustUnmarshal(iterator.Value(), &deQueue)
46-
deQueues = append(deQueues, deQueue)
47-
}
48-
return deQueues
49-
}
50-
51-
// GetDECount retrieves the current count of DE for a given address from the context's KVStore.
52-
func (k Keeper) GetDECount(ctx sdk.Context, address sdk.AccAddress) uint64 {
53-
deQueue := k.GetDEQueue(ctx, address)
54-
if deQueue.Head <= deQueue.Tail {
55-
return deQueue.Tail - deQueue.Head
56-
}
57-
58-
return k.GetParams(ctx).MaxDESize - (deQueue.Head - deQueue.Tail)
25+
// HasDE checks if a DE object exists in the context's KVStore.
26+
func (k Keeper) HasDE(ctx sdk.Context, address sdk.AccAddress, de types.DE) bool {
27+
return ctx.KVStore(k.storeKey).Has(types.DEStoreKey(address, de))
5928
}
6029

61-
// SetDE sets a DE object in the context's KVStore for a given address and index.
62-
func (k Keeper) SetDE(ctx sdk.Context, address sdk.AccAddress, index uint64, de types.DE) {
63-
ctx.KVStore(k.storeKey).Set(types.DEIndexStoreKey(address, index), k.cdc.MustMarshal(&de))
30+
// SetDE sets a DE object in the context's KVStore for a given address.
31+
func (k Keeper) SetDE(ctx sdk.Context, address sdk.AccAddress, de types.DE) {
32+
ctx.KVStore(k.storeKey).Set(types.DEStoreKey(address, de), []byte{1})
6433
}
6534

66-
// GetDE retrieves a DE object from the context's KVStore for a given address and index.
35+
// GetFirstDE retrieves a DE object from the context's KVStore for a given address.
6736
// Returns an error if DE is not found.
68-
func (k Keeper) GetDE(ctx sdk.Context, address sdk.AccAddress, index uint64) (types.DE, error) {
69-
bz := ctx.KVStore(k.storeKey).Get(types.DEIndexStoreKey(address, index))
70-
if bz == nil {
71-
return types.DE{}, types.ErrDENotFound.Wrapf(
72-
"failed to get DE with address %s index %d",
73-
address,
74-
index,
75-
)
37+
func (k Keeper) GetFirstDE(ctx sdk.Context, address sdk.AccAddress) (types.DE, error) {
38+
iterator := k.GetDEByAddressIterator(ctx, address)
39+
defer iterator.Close()
40+
41+
if !iterator.Valid() {
42+
return types.DE{}, types.ErrDENotFound.Wrapf("failed to get DE with address %s", address)
7643
}
77-
var de types.DE
78-
k.cdc.MustUnmarshal(bz, &de)
44+
45+
_, de := types.ExtractValueFromDEStoreKey(iterator.Key())
7946
return de, nil
8047
}
8148

8249
// DeleteDE removes a DE object from the context's KVStore for a given address and index.
83-
func (k Keeper) DeleteDE(ctx sdk.Context, address sdk.AccAddress, index uint64) {
84-
ctx.KVStore(k.storeKey).Delete(types.DEIndexStoreKey(address, index))
50+
func (k Keeper) DeleteDE(ctx sdk.Context, address sdk.AccAddress, de types.DE) {
51+
ctx.KVStore(k.storeKey).Delete(types.DEStoreKey(address, de))
8552
}
8653

8754
// GetDEIterator function gets an iterator over all de from the context's KVStore
@@ -94,10 +61,9 @@ func (k Keeper) GetDEsGenesis(ctx sdk.Context) []types.DEGenesis {
9461
var des []types.DEGenesis
9562
iterator := k.GetDEIterator(ctx)
9663
defer iterator.Close()
64+
9765
for ; iterator.Valid(); iterator.Next() {
98-
var de types.DE
99-
k.cdc.MustUnmarshal(iterator.Value(), &de)
100-
address, _ := types.AddressAndIndexFromDEStoreKey(iterator.Key())
66+
address, de := types.ExtractValueFromDEStoreKey(iterator.Key())
10167
des = append(des, types.DEGenesis{
10268
Address: address.String(),
10369
DE: de,
@@ -106,45 +72,38 @@ func (k Keeper) GetDEsGenesis(ctx sdk.Context) []types.DEGenesis {
10672
return des
10773
}
10874

109-
// NextQueueValue returns next value of head/tail for DE queue
110-
func (k Keeper) NextQueueValue(ctx sdk.Context, val uint64) uint64 {
111-
nextVal := (val + 1) % k.GetParams(ctx).MaxDESize
112-
return nextVal
113-
}
114-
11575
// HandleSetDEs sets multiple DE objects for a given address in the context's KVStore,
116-
// if tail reaches to head, return err as DE is full
76+
// if the given DEs reach maximum limit, return err as DE will be over the limit.
11777
func (k Keeper) HandleSetDEs(ctx sdk.Context, address sdk.AccAddress, des []types.DE) error {
118-
deQueue := k.GetDEQueue(ctx, address)
119-
78+
added := uint64(0)
12079
for _, de := range des {
121-
k.SetDE(ctx, address, deQueue.Tail, de)
122-
deQueue.Tail = k.NextQueueValue(ctx, deQueue.Tail)
123-
124-
if deQueue.Tail == deQueue.Head {
125-
return types.ErrDEQueueFull.Wrap(fmt.Sprintf("DE size exceeds %d", k.GetParams(ctx).MaxDESize))
80+
if k.HasDE(ctx, address, de) {
81+
continue
12682
}
127-
}
12883

129-
k.SetDEQueue(ctx, deQueue)
84+
k.SetDE(ctx, address, de)
85+
added++
86+
}
13087

88+
cnt := k.GetDECount(ctx, address)
89+
if cnt+added > k.GetParams(ctx).MaxDESize {
90+
return types.ErrDEReachMaximumLimit.Wrapf("DE size exceeds %d", k.GetParams(ctx).MaxDESize)
91+
}
92+
k.SetDECount(ctx, address, cnt+uint64(len(des)))
13193
return nil
13294
}
13395

134-
// PollDE retrieves and removes the DE object at the head of the DEQueue for a given address,
135-
// then increments the head index in the DEQueue.
136-
// Returns an error if the DE object could not be retrieved.
96+
// PollDE retrieves and removes the first DE object being retrieved from the iterator of
97+
// the given address. Returns an error if the DE object could not be retrieved.
13798
func (k Keeper) PollDE(ctx sdk.Context, address sdk.AccAddress) (types.DE, error) {
138-
deQueue := k.GetDEQueue(ctx, address)
139-
de, err := k.GetDE(ctx, address, deQueue.Head)
99+
de, err := k.GetFirstDE(ctx, address)
140100
if err != nil {
141101
return types.DE{}, err
142102
}
143103

144-
k.DeleteDE(ctx, address, deQueue.Head)
145-
146-
deQueue.Head = k.NextQueueValue(ctx, deQueue.Head)
147-
k.SetDEQueue(ctx, deQueue)
104+
cnt := k.GetDECount(ctx, address)
105+
k.SetDECount(ctx, address, cnt-1)
106+
k.DeleteDE(ctx, address, de)
148107

149108
return de, nil
150109
}

0 commit comments

Comments
 (0)