@@ -3,8 +3,8 @@ package epochkghandler
33import (
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
2223func 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
2629type 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
3136func (* 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
97108func (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