Skip to content
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
1 change: 1 addition & 0 deletions api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,7 @@ func NewApiServer(config config.Config) *ApiServer {
g.Get("/events/:eventId/follow-state", app.v1EventFollowState)
g.Post("/events/:eventId/follow", app.requireAuthMiddleware, app.requireWriteScope, app.postV1EventFollow)
g.Delete("/events/:eventId/follow", app.requireAuthMiddleware, app.requireWriteScope, app.deleteV1EventFollow)
g.Post("/events/:eventId/submit", app.requireAuthMiddleware, app.requireWriteScope, app.postV1EventSubmitToContest)

g.Get("/tracks/:trackId/comments", app.v1TrackComments)
g.Get("/tracks/:trackId/comment_count", app.v1TrackCommentCount)
Expand Down
79 changes: 79 additions & 0 deletions api/v1_events_submit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package api

import (
"encoding/json"
"strconv"
"time"

"api.audius.co/indexer"
"api.audius.co/trashid"
corev1 "github.com/OpenAudio/go-openaudio/pkg/api/core/v1"
"github.com/ethereum/go-ethereum/common"
"github.com/gofiber/fiber/v2"
"go.uber.org/zap"
)

type SubmitToContestBody struct {
TrackID string `json:"track_id"`
}

// postV1EventSubmitToContest enters a track into an open-contest event.
// Open contests don't have a parent track (unlike remix_contest), so we
// can't infer the submission from the remixes table — discovery indexes
// the SubmitToContest action into contest_submissions instead.
func (app *ApiServer) postV1EventSubmitToContest(c *fiber.Ctx) error {
userID := app.getMyId(c)
eventID, err := trashid.DecodeHashId(c.Params("eventId"))
if err != nil {
return fiber.NewError(fiber.StatusBadRequest, "invalid event id")
}

body := SubmitToContestBody{}
if err := c.BodyParser(&body); err != nil {
return fiber.NewError(fiber.StatusBadRequest, "invalid body")
}
if body.TrackID == "" {
return fiber.NewError(fiber.StatusBadRequest, "track_id is required")
}
trackID, err := trashid.DecodeHashId(body.TrackID)
if err != nil {
return fiber.NewError(fiber.StatusBadRequest, "invalid track id")
}

signer, err := app.getApiSigner(c)
if err != nil {
return err
}

metadata, err := json.Marshal(map[string]any{
"track_id": trackID,
})
if err != nil {
return err
}

nonce := time.Now().UnixNano()
manageEntityTx := &corev1.ManageEntityLegacy{
Signer: common.HexToAddress(signer.Address).String(),
UserId: int64(userID),
EntityId: int64(eventID),
Action: indexer.Action_SubmitToContest,
EntityType: indexer.Entity_Event,
Nonce: strconv.FormatInt(nonce, 10),
Metadata: string(metadata),
}

response, err := app.sendTransactionWithSigner(manageEntityTx, signer.PrivateKey)
if err != nil {
app.logger.Error("Failed to send SubmitToContest transaction", zap.Error(err))
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"error": "Failed to submit to contest",
})
}

return c.JSON(fiber.Map{
"transaction_hash": response.Msg.GetTransaction().GetHash(),
"block_hash": response.Msg.GetTransaction().GetBlockHash(),
"block_number": response.Msg.GetTransaction().GetHeight(),
})
}
24 changes: 24 additions & 0 deletions ddl/migrations/0203_contest_submissions.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
begin;

-- Backs the new "open contest" event type, where entries are explicit
-- submissions (no parent-track remix relationship). Discovery's entity
-- manager writes a row here when it processes a SubmitToContest action.
-- The existing remix_contest path keeps using the remixes-table join,
-- so this table only carries open_contest entries.
create table if not exists contest_submissions (
contest_id integer not null,
track_id integer not null,
user_id integer not null,
created_at timestamp without time zone not null default current_timestamp,
primary key (contest_id, track_id)
);

create index if not exists contest_submissions_track_id_idx
on contest_submissions using btree (track_id);

create index if not exists contest_submissions_user_id_idx
on contest_submissions using btree (user_id);

comment on table contest_submissions is 'Tracks submitted to an open_contest event. Keyed by (contest_id, track_id); contest_id references events.event_id.';

commit;
4 changes: 4 additions & 0 deletions indexer/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ const (
Action_React = "React"
Action_Unreact = "Unreact"
Action_Report = "Report"
// Action_SubmitToContest entries a track in an open-contest event.
// EntityType is Event, EntityId is the contest event_id, and the
// submitted track_id rides on the metadata JSON ({"track_id": <id>}).
Action_SubmitToContest = "SubmitToContest"
)

const (
Expand Down
Loading