Skip to content

Commit 87d7347

Browse files
committed
check if decryption key is already validated by checking the db and skip validation if key exists
1 parent b0142ea commit 87d7347

File tree

3 files changed

+38
-19
lines changed

3 files changed

+38
-19
lines changed

rolling-shutter/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ require (
1616
github.com/google/go-cmp v0.6.0
1717
github.com/google/uuid v1.6.0
1818
github.com/hashicorp/go-multierror v1.1.1
19+
github.com/hashicorp/golang-lru/v2 v2.0.7
1920
github.com/icza/gog v0.0.0-20240529172513-3355cf65d018
2021
github.com/ipfs/go-log/v2 v2.5.1
2122
github.com/jackc/pgconn v1.14.1
@@ -127,7 +128,6 @@ require (
127128
github.com/hashicorp/errwrap v1.1.0 // indirect
128129
github.com/hashicorp/go-bexpr v0.1.11 // indirect
129130
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect
130-
github.com/hashicorp/golang-lru/v2 v2.0.5 // indirect
131131
github.com/hashicorp/hcl v1.0.0 // indirect
132132
github.com/holiman/bloomfilter/v2 v2.0.3 // indirect
133133
github.com/holiman/uint256 v1.2.4 // indirect

rolling-shutter/go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -418,8 +418,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
418418
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
419419
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs=
420420
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
421-
github.com/hashicorp/golang-lru/v2 v2.0.5 h1:wW7h1TG88eUIJ2i69gaE3uNVtEPIagzhGvHgwfx2Vm4=
422-
github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
421+
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
422+
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
423423
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
424424
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
425425
github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 h1:3JQNjnMRil1yD0IfZKHF9GxxWKDJGj8I0IqOUol//sw=

rolling-shutter/keyper/epochkghandler/key.go

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ package epochkghandler
33
import (
44
"bytes"
55
"context"
6-
"math"
76

7+
lru "github.com/hashicorp/golang-lru/v2"
88
"github.com/jackc/pgx/v4"
99
"github.com/jackc/pgx/v4/pgxpool"
1010
pubsub "github.com/libp2p/go-libp2p-pubsub"
@@ -14,18 +14,23 @@ import (
1414
"github.com/shutter-network/shutter/shlib/shcrypto"
1515

1616
"github.com/shutter-network/rolling-shutter/rolling-shutter/keyper/database"
17+
"github.com/shutter-network/rolling-shutter/rolling-shutter/medley"
1718
"github.com/shutter-network/rolling-shutter/rolling-shutter/p2p"
1819
"github.com/shutter-network/rolling-shutter/rolling-shutter/p2pmsg"
1920
"github.com/shutter-network/rolling-shutter/rolling-shutter/shdb"
2021
)
2122

2223
func NewDecryptionKeyHandler(config Config, dbpool *pgxpool.Pool) p2p.MessageHandler {
23-
return &DecryptionKeyHandler{config: config, dbpool: dbpool}
24+
// Not catching the error as it only can happen if non-positive size was applied
25+
cache, _ := lru.New[shcrypto.EpochSecretKey, []byte](1024)
26+
return &DecryptionKeyHandler{config: config, dbpool: dbpool, cache: cache}
2427
}
2528

2629
type DecryptionKeyHandler struct {
2730
config Config
2831
dbpool *pgxpool.Pool
32+
// keep 1024 verified keys in Cache to skip additional verifications
33+
cache *lru.Cache[shcrypto.EpochSecretKey, []byte]
2934
}
3035

3136
func (*DecryptionKeyHandler) MessagePrototypes() []p2pmsg.Message {
@@ -38,34 +43,33 @@ func (handler *DecryptionKeyHandler) ValidateMessage(ctx context.Context, msg p2
3843
return pubsub.ValidationReject,
3944
errors.Errorf("instance ID mismatch (want=%d, have=%d)", handler.config.GetInstanceID(), key.GetInstanceID())
4045
}
41-
if key.Eon > math.MaxInt64 {
42-
return pubsub.ValidationReject, errors.Errorf("eon %d overflows int64", key.Eon)
46+
eon, err := medley.Uint64ToInt64Safe(key.Eon)
47+
if err != nil {
48+
return pubsub.ValidationReject, errors.Wrapf(err, "overflow error while converting eon to int64 %d", eon)
4349
}
4450

4551
queries := database.New(handler.dbpool)
46-
47-
_, isKeyper, err := queries.GetKeyperIndex(ctx, int64(key.Eon), handler.config.GetAddress())
52+
_, isKeyper, err := queries.GetKeyperIndex(ctx, eon, handler.config.GetAddress())
4853
if err != nil {
4954
return pubsub.ValidationReject, err
5055
}
5156
if !isKeyper {
5257
log.Debug().Uint64("eon", key.Eon).Msg("Ignoring decryptionKey for eon; we're not a Keyper")
5358
return pubsub.ValidationReject, nil
5459
}
55-
56-
dkgResultDB, err := queries.GetDKGResultForKeyperConfigIndex(ctx, int64(key.Eon))
57-
if err == pgx.ErrNoRows {
58-
return pubsub.ValidationReject, errors.Errorf("no DKG result found for eon %d", key.Eon)
60+
dkgResultDB, err := queries.GetDKGResultForKeyperConfigIndex(ctx, eon)
61+
if errors.Is(err, pgx.ErrNoRows) {
62+
return pubsub.ValidationReject, errors.Errorf("no DKG result found for eon %d", eon)
5963
}
6064
if err != nil {
61-
return pubsub.ValidationReject, errors.Wrapf(err, "failed to get dkg result for eon %d from db", key.Eon)
65+
return pubsub.ValidationReject, errors.Wrapf(err, "failed to get dkg result for eon %d from db", eon)
6266
}
6367
if !dkgResultDB.Success {
64-
return pubsub.ValidationReject, errors.Errorf("no successful DKG result found for eon %d", key.Eon)
68+
return pubsub.ValidationReject, errors.Errorf("no successful DKG result found for eon %d", eon)
6569
}
6670
pureDKGResult, err := shdb.DecodePureDKGResult(dkgResultDB.PureResult)
6771
if err != nil {
68-
return pubsub.ValidationReject, errors.Wrapf(err, "error while decoding pure DKG result for eon %d", key.Eon)
72+
return pubsub.ValidationReject, errors.Wrapf(err, "error while decoding pure DKG result for eon %d", eon)
6973
}
7074

7175
if len(key.Keys) == 0 {
@@ -74,19 +78,26 @@ func (handler *DecryptionKeyHandler) ValidateMessage(ctx context.Context, msg p2
7478
if len(key.Keys) > int(handler.config.GetMaxNumKeysPerMessage()) {
7579
return pubsub.ValidationReject, errors.Errorf("too many keys in message (%d > %d)", len(key.Keys), handler.config.GetMaxNumKeysPerMessage())
7680
}
81+
7782
for i, k := range key.Keys {
7883
epochSecretKey, err := k.GetEpochSecretKey()
7984
if err != nil {
8085
return pubsub.ValidationReject, err
8186
}
87+
identity, exists := handler.cache.Get(*epochSecretKey)
88+
if exists {
89+
if bytes.Equal(k.Identity, identity) {
90+
continue
91+
}
92+
return pubsub.ValidationReject, errors.Errorf("epoch secret key for identity %x is not valid", k.Identity)
93+
}
8294
ok, err := shcrypto.VerifyEpochSecretKey(epochSecretKey, pureDKGResult.PublicKey, k.Identity)
8395
if err != nil {
8496
return pubsub.ValidationReject, errors.Wrapf(err, "error while checking epoch secret key for identity %x", k.Identity)
8597
}
8698
if !ok {
8799
return pubsub.ValidationReject, errors.Errorf("epoch secret key for identity %x is not valid", k.Identity)
88100
}
89-
90101
if i > 0 && bytes.Compare(k.Identity, key.Keys[i-1].Identity) < 0 {
91102
return pubsub.ValidationReject, errors.Errorf("keys not ordered")
92103
}
@@ -97,7 +108,15 @@ func (handler *DecryptionKeyHandler) ValidateMessage(ctx context.Context, msg p2
97108
func (handler *DecryptionKeyHandler) HandleMessage(ctx context.Context, msg p2pmsg.Message) ([]p2pmsg.Message, error) {
98109
metricsEpochKGDecryptionKeysReceived.Inc()
99110
key := msg.(*p2pmsg.DecryptionKeys)
100-
// Insert the key into the db. We assume that it's valid as it already passed the libp2p
101-
// validator.
111+
// We assume that it's valid as it already passed the libp2p validator.
112+
// Insert the key into the cache.
113+
for _, k := range key.Keys {
114+
epochSecretKey, err := k.GetEpochSecretKey()
115+
if err != nil {
116+
return nil, err
117+
}
118+
handler.cache.Add(*epochSecretKey, k.Identity)
119+
}
120+
// Insert the key into the db.
102121
return nil, database.New(handler.dbpool).InsertDecryptionKeysMsg(ctx, key)
103122
}

0 commit comments

Comments
 (0)