diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2025-07-04 15:39:18 +0200 |
|---|---|---|
| committer | Aleksandr Nogikh <nogikh@google.com> | 2025-07-08 13:37:33 +0000 |
| commit | 45106a5dba83f655b716a39fb66477ee3f1d430c (patch) | |
| tree | c88a1f347a3c6c42afeb6b14f13586619a5d9d94 /syz-cluster/pkg | |
| parent | 1cde38e3b75bb13c11e17a32b0547fb77fb840fa (diff) | |
syz-cluster: use shorter report IDs
Since these may be included into email addresses, keep them short.
Diffstat (limited to 'syz-cluster/pkg')
| -rw-r--r-- | syz-cluster/pkg/db/report_repo.go | 35 | ||||
| -rw-r--r-- | syz-cluster/pkg/db/spanner.go | 6 |
2 files changed, 37 insertions, 4 deletions
diff --git a/syz-cluster/pkg/db/report_repo.go b/syz-cluster/pkg/db/report_repo.go index 4e039c4a7..c99e4a69d 100644 --- a/syz-cluster/pkg/db/report_repo.go +++ b/syz-cluster/pkg/db/report_repo.go @@ -5,9 +5,11 @@ package db import ( "context" + "crypto/rand" + "encoding/hex" + "fmt" "cloud.google.com/go/spanner" - "github.com/google/uuid" ) type ReportRepository struct { @@ -27,10 +29,25 @@ func NewReportRepository(client *spanner.Client) *ReportRepository { } func (repo *ReportRepository) Insert(ctx context.Context, rep *SessionReport) error { - if rep.ID == "" { - rep.ID = uuid.NewString() + if rep.ID != "" { + return repo.genericEntityOps.Insert(ctx, rep) } - return repo.genericEntityOps.Insert(ctx, rep) + const attempts = 3 + for i := 0; i < attempts; i++ { + var err error + rep.ID, err = randomReportID() + if err != nil { + return err + } + err = repo.genericEntityOps.Insert(ctx, rep) + if err == errEntityExists { + continue + } + return err + } + // We shouldn't be getting here until we have sent out billions of reports. + // But let's return some error to still exit gracefully. + return fmt.Errorf("failed to pick a non-existing report ID") } func (repo *ReportRepository) ListNotReported(ctx context.Context, reporter string, @@ -44,3 +61,13 @@ func (repo *ReportRepository) ListNotReported(ctx context.Context, reporter stri addLimit(&stmt, limit) return repo.readEntities(ctx, stmt) } + +// As report ID may be included in the email address, we'd prefer it to be shorter than a typical UUID. +// A 16 byte hex ID should be good enough. +func randomReportID() (string, error) { + data := make([]byte, 8) + if _, err := rand.Read(data); err != nil { + return "", err + } + return hex.EncodeToString(data), nil +} diff --git a/syz-cluster/pkg/db/spanner.go b/syz-cluster/pkg/db/spanner.go index 1aee715f8..1c973ab46 100644 --- a/syz-cluster/pkg/db/spanner.go +++ b/syz-cluster/pkg/db/spanner.go @@ -28,6 +28,7 @@ import ( "github.com/golang-migrate/migrate/v4/source/iofs" "google.golang.org/api/iterator" "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) type ParsedURI struct { @@ -325,6 +326,8 @@ func (g *genericEntityOps[EntityType, KeyType]) Update(ctx context.Context, key return err } +var errEntityExists = errors.New("entity already exists") + func (g *genericEntityOps[EntityType, KeyType]) Insert(ctx context.Context, obj *EntityType) error { _, err := g.client.ReadWriteTransaction(ctx, func(ctx context.Context, txn *spanner.ReadWriteTransaction) error { @@ -334,6 +337,9 @@ func (g *genericEntityOps[EntityType, KeyType]) Insert(ctx context.Context, obj } return txn.BufferWrite([]*spanner.Mutation{insert}) }) + if status.Code(err) == codes.AlreadyExists { + return errEntityExists + } return err } |
