Skip to content

feat: update handler and middleware to allow no sig on keys message and no check on decryption trigger #623

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions rolling-shutter/keyperimpl/shutterservice/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,11 @@ func ValidateDecryptionKeysSignatures(
extra *p2pmsg.ShutterServiceDecryptionKeysExtra,
keyperSet *obskeyperdatabase.KeyperSet,
) (pubsub.ValidationResult, error) {
// Allow for empty signatures and signer indices
if len(extra.SignerIndices) == 0 || len(extra.Signature) == 0 {
return pubsub.ValidationAccept, nil
}

if int32(len(extra.SignerIndices)) != keyperSet.Threshold {
return pubsub.ValidationReject, errors.Errorf("expected %d signers, got %d", keyperSet.Threshold, len(extra.SignerIndices))
}
Expand Down Expand Up @@ -248,12 +253,7 @@ func (h *DecryptionKeysHandler) HandleMessage(ctx context.Context, msg p2pmsg.Me
extra := keys.Extra.(*p2pmsg.DecryptionKeys_Service).Service
serviceDB := database.New(h.dbpool)

identityPreimages := []identitypreimage.IdentityPreimage{}
for _, key := range keys.Keys {
identityPreimage := identitypreimage.IdentityPreimage(key.IdentityPreimage)
identityPreimages = append(identityPreimages, identityPreimage)
}
identitiesHash := computeIdentitiesHash(identityPreimages)
identitiesHash := computeIdentitiesHashFromKeys(keys.GetKeys())
for i, keyperIndex := range extra.SignerIndices {
err := serviceDB.InsertDecryptionSignature(ctx, database.InsertDecryptionSignatureParams{
Eon: int64(keys.Eon),
Expand Down
8 changes: 8 additions & 0 deletions rolling-shutter/keyperimpl/shutterservice/identitieshash.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,11 @@ func computeIdentitiesHashFromShares(shares []*p2pmsg.KeyShare) []byte {
}
return computeIdentitiesHash(identityPreimges)
}

func computeIdentitiesHashFromKeys(keys []*p2pmsg.Key) []byte {
identityPreimges := []identitypreimage.IdentityPreimage{}
for _, key := range keys {
identityPreimges = append(identityPreimges, identitypreimage.IdentityPreimage(key.IdentityPreimage))
}
return computeIdentitiesHash(identityPreimges)
}
46 changes: 5 additions & 41 deletions rolling-shutter/keyperimpl/shutterservice/messagingmiddleware.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package shutterservice

import (
"bytes"
"context"

"github.com/jackc/pgx/v4"
"github.com/jackc/pgx/v4/pgxpool"
pubsub "github.com/libp2p/go-libp2p-pubsub"
"github.com/pkg/errors"
Expand Down Expand Up @@ -105,32 +103,7 @@ func (i *MessagingMiddleware) interceptDecryptionKeyShares(
) (p2pmsg.Message, error) {
queries := database.New(i.dbpool)

currentDecryptionTrigger, err := queries.GetCurrentDecryptionTrigger(ctx, int64(originalMsg.Eon))
if err == pgx.ErrNoRows {
log.Warn().
Uint64("eon", originalMsg.Eon).
Msg("intercepted decryption key shares message with unknown corresponding decryption trigger")
return nil, nil
} else if err != nil {
return nil, errors.Wrapf(err, "failed to get current decryption trigger for eon %d", originalMsg.Eon)
}
if originalMsg.Eon != uint64(currentDecryptionTrigger.Eon) {
log.Warn().
Uint64("eon-got", originalMsg.Eon).
Int64("eon-expected", currentDecryptionTrigger.Eon).
Msg("intercepted decryption key shares message with unexpected eon")
return nil, nil
}

identitiesHash := computeIdentitiesHashFromShares(originalMsg.Shares)
if !bytes.Equal(identitiesHash, currentDecryptionTrigger.IdentitiesHash) {
log.Warn().
Uint64("eon", originalMsg.Eon).
Hex("expectedIdentitiesHash", currentDecryptionTrigger.IdentitiesHash).
Hex("actualIdentitiesHash", identitiesHash).
Msg("intercepted decryption key shares message with unexpected identities hash")
return nil, nil
}

identityPreimages := []identitypreimage.IdentityPreimage{}
for _, share := range originalMsg.Shares {
Expand Down Expand Up @@ -176,32 +149,23 @@ func (i *MessagingMiddleware) interceptDecryptionKeys(
ctx context.Context,
originalMsg *p2pmsg.DecryptionKeys,
) (p2pmsg.Message, error) {
// TODO: update flag in event table to notify the decryption is already done
if originalMsg.Extra != nil {
return originalMsg, nil
}

serviceDB := database.New(i.dbpool)
obsKeyperDB := obskeyperdatabase.New(i.dbpool)
trigger, err := serviceDB.GetCurrentDecryptionTrigger(ctx, int64(originalMsg.Eon))
if err == pgx.ErrNoRows {
log.Warn().
Uint64("eon", originalMsg.Eon).
Msg("unknown decryption trigger for intercepted keys message")
return nil, nil
}
if err != nil {
return nil, errors.Wrapf(err, "failed to get current decryption trigger for eon %d", originalMsg.Eon)
}

keyperSet, err := obsKeyperDB.GetKeyperSetByKeyperConfigIndex(ctx, int64(originalMsg.Eon))
if err != nil {
return nil, errors.Wrapf(err, "failed to get keyper set from database for eon %d", originalMsg.Eon)
}

identitiesHash := computeIdentitiesHashFromKeys(originalMsg.GetKeys())

signatures, err := serviceDB.GetDecryptionSignatures(ctx, database.GetDecryptionSignaturesParams{
Eon: int64(originalMsg.Eon),
IdentitiesHash: trigger.IdentitiesHash,
IdentitiesHash: identitiesHash,
Limit: keyperSet.Threshold,
})
if err != nil {
Expand All @@ -212,7 +176,7 @@ func (i *MessagingMiddleware) interceptDecryptionKeys(
if len(signatures) < int(keyperSet.Threshold) {
log.Debug().
Uint64("eon", originalMsg.Eon).
Hex("identities-hash", trigger.IdentitiesHash).
Hex("identities-hash", identitiesHash).
Int32("threshold", keyperSet.Threshold).
Int("num-signatures", len(signatures)).
Msg("dropping intercepted keys message as signature count is not high enough yet")
Expand Down Expand Up @@ -241,7 +205,7 @@ func (i *MessagingMiddleware) interceptDecryptionKeys(

log.Info().
Uint64("eon", originalMsg.Eon).
Hex("identities-hash", trigger.IdentitiesHash).
Hex("identities-hash", identitiesHash).
Int("num-signatures", len(signatures)).
Int("num-keys", len(msg.Keys)).
Msg("sending keys")
Expand Down
10 changes: 0 additions & 10 deletions rolling-shutter/keyperimpl/shutterservice/newblock.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ func (kpr *Keyper) triggerDecryption(ctx context.Context,
triggeredBlock *syncevent.LatestBlock,
) error {
coreKeyperDB := corekeyperdatabase.New(kpr.dbpool)
serviceDB := servicedatabase.New(kpr.dbpool)

identityPreimages := make(map[int64][]identitypreimage.IdentityPreimage)
lastEonBlock := make(map[int64]int64)
Expand Down Expand Up @@ -143,15 +142,6 @@ func (kpr *Keyper) triggerDecryption(ctx context.Context,
for eon, preImages := range identityPreimages {
sortedIdentityPreimages := sortIdentityPreimages(preImages)

err := serviceDB.SetCurrentDecryptionTrigger(ctx, servicedatabase.SetCurrentDecryptionTriggerParams{
Eon: eon,
TriggeredBlockNumber: triggeredBlock.Number.Int64(),
IdentitiesHash: computeIdentitiesHash(sortedIdentityPreimages),
})
if err != nil {
return errors.Wrap(err, "failed to insert published decryption trigger into db")
}

trigger := epochkghandler.DecryptionTrigger{
// sending last block available for that eon as the key shares will be generated based on the eon associated with this block number
BlockNumber: uint64(lastEonBlock[eon]),
Expand Down