perf: sync protocol and core hardening updates

This commit is contained in:
A 2026-07-11 19:48:26 +08:00
parent 152fed3b87
commit 4390ebf5a9
283 changed files with 29231 additions and 2295 deletions

View file

@ -0,0 +1,162 @@
package postgres
import (
"bytes"
"context"
"crypto/sha256"
"encoding/binary"
"errors"
"fmt"
"sort"
"telesrv/internal/domain"
)
// ReserveAlbumGroup 先按稳定顺序获取整批 key 的事务级 advisory locks,再读取旧绑定
// 并一次性补齐缺失项。锁覆盖不存在的行,因此避免单靠 UNIQUE/ON CONFLICT 时两个实例
// 对重叠批次分别选出不同 grouped_id 的 write-skew。
func (s *MessageStore) ReserveAlbumGroup(ctx context.Context, req domain.AlbumGroupReservationRequest) (int64, error) {
if err := req.Validate(); err != nil {
return 0, err
}
beginner, ok := s.db.(txBeginner)
if !ok {
return 0, errors.New("reserve album group requires transaction-capable postgres handle")
}
tx, err := beginner.Begin(ctx)
if err != nil {
return 0, fmt.Errorf("reserve album group begin: %w", err)
}
defer func() { _ = tx.Rollback(ctx) }()
lockIDs := albumGroupAdvisoryLockIDs(req)
for _, lockID := range lockIDs {
if _, err := tx.Exec(ctx, `SELECT pg_advisory_xact_lock($1)`, lockID); err != nil {
return 0, fmt.Errorf("reserve album group lock: %w", err)
}
}
randomIDs := make([]int64, 0, len(req.Items))
requestedIntents := make(map[int64][]byte, len(req.Items))
for _, item := range req.Items {
randomIDs = append(randomIDs, item.RandomID)
requestedIntents[item.RandomID] = item.IntentHash
}
rows, err := tx.Query(ctx, `
SELECT random_id, grouped_id, intent_hash
FROM album_group_reservations
WHERE sender_user_id = $1
AND peer_type = $2
AND peer_id = $3
AND random_id = ANY($4::bigint[])
ORDER BY random_id`, req.SenderUserID, string(req.Peer.Type), req.Peer.ID, randomIDs)
if err != nil {
return 0, fmt.Errorf("reserve album group read existing: %w", err)
}
existingGroups := make(map[int64]struct{}, 2)
for rows.Next() {
var randomID int64
var groupedID int64
var intentHash []byte
if err := rows.Scan(&randomID, &groupedID, &intentHash); err != nil {
rows.Close()
return 0, fmt.Errorf("reserve album group scan existing: %w", err)
}
if !bytes.Equal(intentHash, requestedIntents[randomID]) {
rows.Close()
return 0, fmt.Errorf("%w: album random_id %d intent changed", domain.ErrMessageRandomIDDuplicate, randomID)
}
existingGroups[groupedID] = struct{}{}
}
readErr := rows.Err()
rows.Close()
if readErr != nil {
return 0, fmt.Errorf("reserve album group iterate existing: %w", readErr)
}
if len(existingGroups) > 1 {
return 0, fmt.Errorf("%w: album request spans multiple grouped_id values", domain.ErrMessageRandomIDDuplicate)
}
groupedID := req.ProposedGroupedID
for existingGroup := range existingGroups {
groupedID = existingGroup
}
for _, item := range req.Items {
if _, err := tx.Exec(ctx, `
INSERT INTO album_group_reservations (
sender_user_id, peer_type, peer_id, random_id, intent_hash, grouped_id
)
VALUES ($1, $2, $3, $4, $5, $6)
ON CONFLICT (sender_user_id, peer_type, peer_id, random_id) DO NOTHING`,
req.SenderUserID, string(req.Peer.Type), req.Peer.ID, item.RandomID, item.IntentHash, groupedID); err != nil {
return 0, fmt.Errorf("reserve album group insert binding: %w", err)
}
}
// 防御性复核:advisory lock 协议若被未来代码绕过,也不能把拆组状态作为成功返回。
rows, err = tx.Query(ctx, `
SELECT random_id, grouped_id, intent_hash
FROM album_group_reservations
WHERE sender_user_id = $1
AND peer_type = $2
AND peer_id = $3
AND random_id = ANY($4::bigint[])`,
req.SenderUserID, string(req.Peer.Type), req.Peer.ID, randomIDs)
if err != nil {
return 0, fmt.Errorf("reserve album group verify: %w", err)
}
verified := 0
for rows.Next() {
var randomID, storedGroup int64
var intentHash []byte
if err := rows.Scan(&randomID, &storedGroup, &intentHash); err != nil {
rows.Close()
return 0, fmt.Errorf("reserve album group verify scan: %w", err)
}
if storedGroup != groupedID || !bytes.Equal(intentHash, requestedIntents[randomID]) {
rows.Close()
return 0, fmt.Errorf("%w: album reservation diverged for random_id %d", domain.ErrMessageRandomIDDuplicate, randomID)
}
verified++
}
verifyErr := rows.Err()
rows.Close()
if verifyErr != nil {
return 0, fmt.Errorf("reserve album group verify iterate: %w", verifyErr)
}
if verified != len(req.Items) {
return 0, fmt.Errorf("%w: album reservation count=%d/%d", domain.ErrMessageRandomIDDuplicate, verified, len(req.Items))
}
if err := tx.Commit(ctx); err != nil {
return 0, fmt.Errorf("reserve album group commit: %w", err)
}
return groupedID, nil
}
// albumGroupAdvisoryLockIDs 对每个业务 key 派生一个 64-bit advisory lock,并按数值
// 排序、去重。hash 碰撞最多造成无害串行化;排序保证重叠批次不会互相反序死锁。
func albumGroupAdvisoryLockIDs(req domain.AlbumGroupReservationRequest) []int64 {
ids := make([]int64, 0, len(req.Items))
for _, item := range req.Items {
h := sha256.New()
_, _ = h.Write([]byte("telesrv:album-group:v1\x00"))
var word [8]byte
binary.BigEndian.PutUint64(word[:], uint64(req.SenderUserID))
_, _ = h.Write(word[:])
_, _ = h.Write([]byte(req.Peer.Type))
binary.BigEndian.PutUint64(word[:], uint64(req.Peer.ID))
_, _ = h.Write(word[:])
binary.BigEndian.PutUint64(word[:], uint64(item.RandomID))
_, _ = h.Write(word[:])
sum := h.Sum(nil)
ids = append(ids, int64(binary.BigEndian.Uint64(sum[:8])))
}
sort.Slice(ids, func(i, j int) bool { return ids[i] < ids[j] })
out := ids[:0]
for _, id := range ids {
if len(out) == 0 || out[len(out)-1] != id {
out = append(out, id)
}
}
return out
}