Skip to content

Commit

Permalink
Use only a single query for GetIDWithMaxHeight
Browse files Browse the repository at this point in the history
  • Loading branch information
fasmat committed Feb 14, 2025
1 parent 69816ac commit 2d7b249
Show file tree
Hide file tree
Showing 5 changed files with 14 additions and 45 deletions.
9 changes: 2 additions & 7 deletions api/grpcserver/v2alpha1/activation.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,15 +242,10 @@ func (s *ActivationService) ActivationsCount(
}

func (s *ActivationService) Highest(
ctx context.Context,
_ context.Context,
_ *spacemeshv2alpha1.HighestRequest,
) (*spacemeshv2alpha1.HighestResponse, error) {
var highest types.ATXID
err := s.db.WithTxImmediate(ctx, func(tx sql.Transaction) error {
var err error
highest, err = atxs.GetIDWithMaxHeight(tx, types.EmptyNodeID, atxs.FilterAll)
return err
})
highest, err := atxs.GetIDWithMaxHeight(s.db, types.EmptyNodeID, atxs.FilterAll)
if err != nil {
return &spacemeshv2alpha1.HighestResponse{
Activation: &spacemeshv2alpha1.Activation{
Expand Down
9 changes: 2 additions & 7 deletions api/grpcserver/v2beta1/activation.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,15 +242,10 @@ func (s *ActivationService) ActivationsCount(
}

func (s *ActivationService) Highest(
ctx context.Context,
_ context.Context,
_ *spacemeshv2beta1.HighestRequest,
) (*spacemeshv2beta1.HighestResponse, error) {
var highest types.ATXID
err := s.db.WithTxImmediate(ctx, func(tx sql.Transaction) error {
var err error
highest, err = atxs.GetIDWithMaxHeight(tx, types.EmptyNodeID, atxs.FilterAll)
return err
})
highest, err := atxs.GetIDWithMaxHeight(s.db, types.EmptyNodeID, atxs.FilterAll)
if err != nil {
return &spacemeshv2beta1.HighestResponse{
Activation: &spacemeshv2beta1.Activation{
Expand Down
8 changes: 1 addition & 7 deletions datastore/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,13 +217,7 @@ func (db *CachedDB) IterateMalfeasanceProofs(
// MaxHeightAtx returns the ATX ID with the maximum height.
// Deprecated: replaced by atxs.GetIDWithMaxHeight.
func (db *CachedDB) MaxHeightAtx() (types.ATXID, error) {
var id types.ATXID
err := db.WithTxImmediate(context.Background(), func(tx sql.Transaction) error {
var err error
id, err = atxs.GetIDWithMaxHeight(tx, types.EmptyNodeID, atxs.FilterAll)
return err
})
return id, err
return atxs.GetIDWithMaxHeight(db, types.EmptyNodeID, atxs.FilterAll)
}

// Hint marks which DB should be queried for a certain provided hash.
Expand Down
21 changes: 5 additions & 16 deletions sql/atxs/atxs.go
Original file line number Diff line number Diff line change
Expand Up @@ -518,27 +518,15 @@ func FilterAll(types.ATXID) bool { return true }
// highest ticked atx still in previous epoch and the atxs building on top of it have not been published yet.
// Selecting from the last two epochs to strike a balance between being fair to honest miners while not giving
// unfair advantage for malicious actors who retroactively publish a high tick atx many epochs back.
func GetIDWithMaxHeight(tx sql.Transaction, pref types.NodeID, filter Filter) (types.ATXID, error) {
func GetIDWithMaxHeight(db sql.Executor, pref types.NodeID, filter Filter) (types.ATXID, error) {
if filter == nil {
filter = FilterAll
}

// find max epoch
var maxEpoch types.EpochID
if _, err := tx.Exec("select max(epoch) from atxs;", nil, func(stmt *sql.Statement) bool {
maxEpoch = types.EpochID(uint32(stmt.ColumnInt64(0)))
return false
}); err != nil {
return types.ATXID{}, fmt.Errorf("selecting max epoch: %w", err)
}

var (
rst types.ATXID
highest uint64
)
enc := func(stmt *sql.Statement) {
stmt.BindInt64(1, int64(maxEpoch-1))
}
dec := func(stmt *sql.Statement) bool {
var id types.ATXID
stmt.ColumnBytes(0, id[:])
Expand Down Expand Up @@ -567,20 +555,21 @@ func GetIDWithMaxHeight(tx sql.Transaction, pref types.NodeID, filter Filter) (t
return true
}

_, err := tx.Exec(`
_, err := db.Exec(`
WITH max_epoch AS (SELECT MAX(epoch) AS max_epoch FROM atxs)
SELECT a.id, a.height, a.pubkey
FROM (
SELECT id, base_tick_height + tick_count AS height, pubkey, epoch
FROM atxs
WHERE epoch >= ?1
WHERE epoch >= (SELECT max_epoch FROM max_epoch)-1
) a
WHERE NOT EXISTS (
SELECT 1 FROM identities i WHERE i.pubkey = a.pubkey
) AND NOT EXISTS (
SELECT 1 FROM malfeasance m WHERE m.pubkey = a.pubkey
)
ORDER BY a.height DESC, a.epoch DESC
`, enc, dec)
`, nil, dec)
switch {
case err != nil:
return types.ATXID{}, fmt.Errorf("selecting high-tick atx: %w", err)
Expand Down
12 changes: 4 additions & 8 deletions sql/atxs/atxs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -941,14 +941,10 @@ func TestGetIDWithMaxHeight(t *testing.T) {
if tc.pref > 0 {
pref = sigs[tc.pref].NodeID()
}
var rst types.ATXID
err := db.WithTxImmediate(context.Background(), func(tx sql.Transaction) error {
var err error
rst, err = atxs.GetIDWithMaxHeight(tx, pref, func(id types.ATXID) bool {
_, ok := filtered[id]
return !ok
})
return err

rst, err := atxs.GetIDWithMaxHeight(db, pref, func(id types.ATXID) bool {
_, ok := filtered[id]
return !ok
})
if len(tc.atxs) == 0 || tc.expect < 0 {
require.ErrorIs(t, err, sql.ErrNotFound)
Expand Down

0 comments on commit 2d7b249

Please sign in to comment.