From cdc1925264ffcc4149139ad7daf7ca4f867cb67f Mon Sep 17 00:00:00 2001 From: Raymond Jacobson Date: Tue, 16 Dec 2025 15:16:05 -0800 Subject: [PATCH 1/3] Clean up nodes, add unsplash, /discovery, /content routes --- api/content_node_monitor.go | 229 --------------------- api/content_nodes.go | 39 ++++ api/discovery_nodes.go | 39 ++++ api/health_check.go | 31 +-- api/{validator.go => request_validator.go} | 0 api/server.go | 26 +-- api/server_test.go | 11 +- api/unsplash.go | 92 +++++++++ api/v1_claim_rewards.go | 18 +- api/v1_claim_rewards_test.go | 14 +- api/v1_coins_post_redeem.go | 2 +- api/v1_validators.go | 20 +- config/config.go | 50 +++-- config/nodes.go | 183 +--------------- rendezvous/rendezvous.go | 16 +- 15 files changed, 272 insertions(+), 498 deletions(-) delete mode 100644 api/content_node_monitor.go create mode 100644 api/content_nodes.go create mode 100644 api/discovery_nodes.go rename api/{validator.go => request_validator.go} (100%) create mode 100644 api/unsplash.go diff --git a/api/content_node_monitor.go b/api/content_node_monitor.go deleted file mode 100644 index f284ea70..00000000 --- a/api/content_node_monitor.go +++ /dev/null @@ -1,229 +0,0 @@ -package api - -import ( - "context" - "fmt" - "net/http" - "sync" - "time" - - "connectrpc.com/connect" - ethv1 "github.com/OpenAudio/go-openaudio/pkg/api/eth/v1" - - "api.audius.co/config" - "github.com/OpenAudio/go-openaudio/pkg/sdk" - "go.uber.org/zap" -) - -// ContentNodeMonitor pings storage enabled nodes on a timer and caches a list -// of the ones that responded. -type ContentNodeMonitor struct { - openAudioSDK *sdk.OpenAudioSDK - config config.Config - healthyNodes []config.Node - mu sync.RWMutex - stopChan chan struct{} - running bool - runningMu sync.Mutex - httpClient *http.Client - logger *zap.Logger -} - -func NewContentNodeMonitor(cfg config.Config, logger *zap.Logger) *ContentNodeMonitor { - openAudioSDK := sdk.NewOpenAudioSDK(cfg.AudiusdURL) - // Filter nodes to only include those with storage enabled - var storageEnabledNodes []config.Node - for _, node := range cfg.Nodes { - if !node.IsStorageDisabled { - storageEnabledNodes = append(storageEnabledNodes, node) - } - } - - return &ContentNodeMonitor{ - openAudioSDK: openAudioSDK, - config: cfg, - healthyNodes: storageEnabledNodes, - httpClient: &http.Client{ - Timeout: 5 * time.Second, - }, - stopChan: make(chan struct{}), - logger: logger, - } -} - -func (m *ContentNodeMonitor) Start() error { - m.runningMu.Lock() - defer m.runningMu.Unlock() - - if m.running { - return fmt.Errorf("monitor is already running") - } - - m.running = true - - go m.monitorLoop() - - return nil -} - -func (m *ContentNodeMonitor) Stop() { - m.runningMu.Lock() - defer m.runningMu.Unlock() - - if !m.running { - return - } - - close(m.stopChan) - m.running = false -} - -func (m *ContentNodeMonitor) GetContentNodes() []config.Node { - m.mu.RLock() - defer m.mu.RUnlock() - - // Return a copy to prevent external modification - result := make([]config.Node, len(m.healthyNodes)) - copy(result, m.healthyNodes) - return result -} - -// monitorLoop runs the main monitoring loop. (every 2 minutes) -func (m *ContentNodeMonitor) monitorLoop() { - ticker := time.NewTicker(2 * time.Minute) - defer ticker.Stop() - - // Perform initial health check - m.updateHealthyNodes() - - for { - select { - case <-ticker.C: - m.updateHealthyNodes() - case <-m.stopChan: - return - } - } -} - -func (m *ContentNodeMonitor) getRegisteredNodes(ctx context.Context) ([]config.Node, error) { - endpoints, err := m.openAudioSDK.Eth.GetRegisteredEndpoints(ctx, connect.NewRequest(ðv1.GetRegisteredEndpointsRequest{})) - if err != nil { - return []config.Node{}, err - } - var nodes []config.Node - var endpointStrings []string - for _, endpoint := range endpoints.Msg.Endpoints { - if endpoint.ServiceType == "content-node" || endpoint.ServiceType == "validator" { - nodes = append(nodes, config.Node{ - Endpoint: endpoint.Endpoint, - DelegateOwnerWallet: endpoint.DelegateWallet, - OwnerWallet: endpoint.Owner, - IsStorageDisabled: false, - }) - endpointStrings = append(endpointStrings, endpoint.Endpoint) - } - } - return nodes, nil -} - -func (m *ContentNodeMonitor) updateHealthyNodes() { - // Use a mutex to ensure only one health check runs at a time - m.runningMu.Lock() - defer m.runningMu.Unlock() - - if !m.running { - return - } - - // Create a context with timeout for the entire health check process - ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) - defer cancel() - - // Channel to collect results - type healthResult struct { - node config.Node - healthy bool - } - - registeredNodes, err := m.getRegisteredNodes(ctx) - if err != nil { - m.logger.Error("Failed to get registered nodes", zap.Error(err)) - return - } - - resultChan := make(chan healthResult, len(registeredNodes)) - - // Check health in parallel - for _, node := range registeredNodes { - go func(n config.Node) { - healthy := m.checkSingleNodeHealth(ctx, n) - resultChan <- healthResult{node: n, healthy: healthy} - }(node) - } - - var healthyNodes []config.Node - -nodeCheckLoop: - for i := 0; i < len(registeredNodes); i++ { - select { - case result := <-resultChan: - if result.healthy { - healthyNodes = append(healthyNodes, result.node) - } - // Done indicates timeout, so we break and stop checking - case <-ctx.Done(): - m.logger.Error("Content node health check timed out", - zap.Error(ctx.Err()), - zap.Int("nodes_checked", i), - zap.Int("total_nodes", len(registeredNodes))) - break nodeCheckLoop - } - } - - m.mu.Lock() - m.healthyNodes = healthyNodes - m.mu.Unlock() - - m.logger.Debug("Content node health check completed", - zap.Int("healthy_nodes", len(healthyNodes)), - zap.Int("total_nodes", len(registeredNodes))) -} - -func (m *ContentNodeMonitor) checkSingleNodeHealth(ctx context.Context, node config.Node) bool { - const maxRetries = 3 - - for attempt := range maxRetries { - if m.checkNodeEndpoint(ctx, node) { - return true - } - - // Retry w/ simple backoff - if attempt < maxRetries-1 { - select { - case <-time.After(time.Duration(attempt+1) * time.Second): - case <-ctx.Done(): - return false - } - } - } - - return false -} - -func (m *ContentNodeMonitor) checkNodeEndpoint(ctx context.Context, node config.Node) bool { - healthURL := fmt.Sprintf("%s/health_check", node.Endpoint) - - req, err := http.NewRequestWithContext(ctx, "GET", healthURL, nil) - if err != nil { - return false - } - - resp, err := m.httpClient.Do(req) - if err != nil { - return false - } - defer resp.Body.Close() - - return resp.StatusCode == http.StatusOK -} diff --git a/api/content_nodes.go b/api/content_nodes.go new file mode 100644 index 00000000..f3f525fa --- /dev/null +++ b/api/content_nodes.go @@ -0,0 +1,39 @@ +package api + +import ( + "strings" + + "github.com/gofiber/fiber/v2" +) + +func (app *ApiServer) contentNodes(c *fiber.Ctx) error { + var contentNodes []fiber.Map + for _, node := range app.validators.GetNodes() { + if node.ServiceType == "content-node" { + contentNodes = append(contentNodes, fiber.Map{ + "id": node.Id, + "owner": node.Owner, + "endpoint": node.Endpoint, + "delegateWallet": node.DelegateWallet, + "serviceType": node.ServiceType, + "registeredAt": node.RegisteredAt, + }) + } + } + + if strings.HasSuffix(c.Path(), "/verbose") { + return c.JSON(fiber.Map{ + "data": contentNodes, + }) + } + + // Return just URLs as strings + urls := make([]string, len(contentNodes)) + for i, node := range contentNodes { + urls[i] = node["endpoint"].(string) + } + + return c.JSON(fiber.Map{ + "data": urls, + }) +} diff --git a/api/discovery_nodes.go b/api/discovery_nodes.go new file mode 100644 index 00000000..ed94e894 --- /dev/null +++ b/api/discovery_nodes.go @@ -0,0 +1,39 @@ +package api + +import ( + "strings" + + "github.com/gofiber/fiber/v2" +) + +func (app *ApiServer) discoveryNodes(c *fiber.Ctx) error { + var discoveryNodes []fiber.Map + for _, node := range app.validators.GetNodes() { + if node.ServiceType == "discovery-node" { + discoveryNodes = append(discoveryNodes, fiber.Map{ + "id": node.Id, + "owner": node.Owner, + "endpoint": node.Endpoint, + "delegateWallet": node.DelegateWallet, + "serviceType": node.ServiceType, + "registeredAt": node.RegisteredAt, + }) + } + } + + if strings.HasSuffix(c.Path(), "/verbose") { + return c.JSON(fiber.Map{ + "data": discoveryNodes, + }) + } + + // Return just URLs as strings + urls := make([]string, len(discoveryNodes)) + for i, node := range discoveryNodes { + urls[i] = node["endpoint"].(string) + } + + return c.JSON(fiber.Map{ + "data": urls, + }) +} diff --git a/api/health_check.go b/api/health_check.go index 4131681f..54fe30af 100644 --- a/api/health_check.go +++ b/api/health_check.go @@ -2,8 +2,8 @@ package api import ( "context" - "slices" + "api.audius.co/config" core_indexer "api.audius.co/indexer" "connectrpc.com/connect" corev1 "github.com/OpenAudio/go-openaudio/pkg/api/core/v1" @@ -18,6 +18,7 @@ type contentNode struct { } type networkInfo struct { + Validators []config.Node `json:"validators"` ContentNodes []contentNode `json:"content_nodes"` } @@ -63,19 +64,6 @@ func (app *ApiServer) healthCheck(c *fiber.Ctx) error { return err } - healthyNodes := app.contentNodeMonitor.GetContentNodes() - // Convert config.Node to contentNode - contentNodes := make([]contentNode, 0, len(healthyNodes)) - for _, node := range healthyNodes { - // icky reaching into config to check upload nodes - if slices.Contains(app.config.UploadNodes, node.Endpoint) { - contentNodes = append(contentNodes, contentNode{ - DelegateOwnerWallet: node.DelegateOwnerWallet, - Endpoint: node.Endpoint, - }) - } - } - coreIndexerHealth, err := app.getCoreIndexerHealth(c.Context()) if err != nil { app.logger.Error("Failed to get core indexer health", zap.Error(err)) @@ -89,9 +77,24 @@ func (app *ApiServer) healthCheck(c *fiber.Ctx) error { } } + nodes := app.validators.GetNodes() + contentNodes := make([]contentNode, 0) + for _, node := range nodes { + for _, uploadNode := range app.config.UploadNodes { + if node.Endpoint == uploadNode { + contentNodes = append(contentNodes, contentNode{ + DelegateOwnerWallet: node.DelegateWallet, + Endpoint: node.Endpoint, + }) + break + } + } + } + health := healthCheckResponse{ CoreIndexer: coreIndexerHealth, Network: networkInfo{ + Validators: nodes, ContentNodes: contentNodes, }, } diff --git a/api/validator.go b/api/request_validator.go similarity index 100% rename from api/validator.go rename to api/request_validator.go diff --git a/api/server.go b/api/server.go index 87870871..5d628aa0 100644 --- a/api/server.go +++ b/api/server.go @@ -183,12 +183,6 @@ func NewApiServer(config config.Config) *ApiServer { panic(err) } - var contentNodeMonitor *ContentNodeMonitor - if config.ContentNodeMonitor { - contentNodeMonitor = NewContentNodeMonitor(config, logger) - contentNodeMonitor.Start() - } - app := &ApiServer{ App: fiber.New(fiber.Config{ JSONEncoder: json.Marshal, @@ -225,7 +219,6 @@ func NewApiServer(config config.Config) *ApiServer { birdeyeClient: birdeye.New(config.BirdeyeToken), solanaRpcClient: solanaRpc, meteoraDbcClient: meteoraDbcClient, - contentNodeMonitor: contentNodeMonitor, } // Set up a custom decoder for HashIds so they can be parsed in lists @@ -588,6 +581,16 @@ func NewApiServer(config config.Config) *ApiServer { // Solana health app.Get("/solana/health", app.solanaHealth) + // Nodes + app.Get("/validators", app.v1Validators) + app.Get("/discovery", app.discoveryNodes) + app.Get("/discovery/verbose", app.discoveryNodes) + app.Get("/content", app.contentNodes) + app.Get("/content/verbose", app.contentNodes) + + // Unsplash proxy + app.All("/unsplash/*", app.unsplash) + app.Static("/", "./static") // Disable swagger in test environments, because it will slow things down a lot @@ -658,7 +661,6 @@ type ApiServer struct { birdeyeClient BirdeyeClient solanaRpcClient *rpc.Client meteoraDbcClient *meteora_dbc.Client - contentNodeMonitor *ContentNodeMonitor validators *Nodes openAudioPool *OpenAudioPool } @@ -669,6 +671,9 @@ func (app *ApiServer) home(c *fiber.Ctx) error { "git": app.config.Git, "started": app.started, "uptime": time.Since(app.started).Truncate(time.Second).String(), + "data": []string{ + "https://discoveryprovider.audius.co", + }, }) } @@ -749,11 +754,6 @@ func (as *ApiServer) Serve() { as.metricsCollector.Shutdown() } - // Shutdown content node monitor if it exists - if as.contentNodeMonitor != nil { - as.contentNodeMonitor.Stop() - } - // Shutdown HLL aggregator if it exists // Removed hllAggregator diff --git a/api/server_test.go b/api/server_test.go index 50922490..33e9cf8e 100644 --- a/api/server_test.go +++ b/api/server_test.go @@ -31,12 +31,11 @@ func emptyTestApp(t *testing.T) *ApiServer { pool := database.CreateTestDatabase(t, "test_api") app := NewApiServer(config.Config{ - Env: "test", - ReadDbUrl: pool.Config().ConnString(), - WriteDbUrl: pool.Config().ConnString(), - RunMigrations: false, - ContentNodeMonitor: false, - EsUrl: "http://localhost:21401", + Env: "test", + ReadDbUrl: pool.Config().ConnString(), + WriteDbUrl: pool.Config().ConnString(), + RunMigrations: false, + EsUrl: "http://localhost:21401", // Dummy key DelegatePrivateKey: "0633fddb74e32b3cbc64382e405146319c11a1a52dc96598e557c5dbe2f31468", SolanaConfig: config.SolanaConfig{RpcProviders: []string{""}, StakingBridgeUsdcTokenAccount: solana.MustPublicKeyFromBase58(config.DevStakingBridgeUsdcTokenAccount)}, diff --git a/api/unsplash.go b/api/unsplash.go new file mode 100644 index 00000000..9002f030 --- /dev/null +++ b/api/unsplash.go @@ -0,0 +1,92 @@ +package api + +import ( + "bytes" + "fmt" + "io" + "math/rand" + "net/http" + "net/url" + "strings" + "time" + + "github.com/gofiber/fiber/v2" +) + +func (app *ApiServer) unsplash(c *fiber.Ctx) error { + targetURL := fmt.Sprintf( + "https://api.unsplash.com%s", + strings.Replace(c.Path(), "/unsplash", "", 1), + ) + + // Copy query parameters from the original request + parsedURL, err := url.Parse(targetURL) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Invalid URL: %v", err)) + } + query := parsedURL.Query() + for key, values := range c.Queries() { + query.Set(key, values) + } + parsedURL.RawQuery = query.Encode() + + unsplashKeys := app.config.UnsplashKeys + if len(unsplashKeys) == 0 { + return fiber.NewError(fiber.StatusInternalServerError, "No Unsplash keys configured") + } + + triedIndices := make(map[int]bool) + rng := rand.New(rand.NewSource(time.Now().UnixNano())) + client := &http.Client{Timeout: 30 * time.Second} + body := c.Body() + + // Try keys randomly until we find one that works or exhaust all keys + for len(triedIndices) < len(unsplashKeys) { + idx := rng.Intn(len(unsplashKeys)) + if triedIndices[idx] { + continue + } + triedIndices[idx] = true + + query.Set("client_id", unsplashKeys[idx]) + parsedURL.RawQuery = query.Encode() + + req, err := http.NewRequestWithContext(c.Context(), c.Method(), parsedURL.String(), bytes.NewReader(body)) + if err != nil { + continue + } + + for key, value := range c.Request().Header.All() { + keyStr := string(key) + if strings.ToLower(keyStr) != "host" { + req.Header.Set(keyStr, string(value)) + } + } + + resp, err := client.Do(req) + if err != nil { + continue + } + + // If successful, proxy the response + if resp.StatusCode >= 200 && resp.StatusCode < 300 { + defer resp.Body.Close() + + for key, values := range resp.Header { + for _, value := range values { + c.Set(key, value) + } + } + c.Status(resp.StatusCode) + body, err := io.ReadAll(resp.Body) + if err != nil { + continue + } + return c.Send(body) + } + + resp.Body.Close() + } + // All keys failed + return fiber.NewError(fiber.StatusBadGateway, "All Unsplash keys failed") +} diff --git a/api/v1_claim_rewards.go b/api/v1_claim_rewards.go index f299195c..55b64ac8 100644 --- a/api/v1_claim_rewards.go +++ b/api/v1_claim_rewards.go @@ -272,15 +272,15 @@ func fetchAttestations( currentIndex++ // Skip if we've already used this owner globally or this specific validator is marked bad - if usedOwners[node.OwnerWallet] || badValidators[node.Endpoint] { + if usedOwners[node.Owner] || badValidators[node.Endpoint] { continue } // Skip if we've already picked this owner in this round - if candidateOwners[node.OwnerWallet] { + if candidateOwners[node.Owner] { continue } candidateNodes = append(candidateNodes, node) - candidateOwners[node.OwnerWallet] = true + candidateOwners[node.Owner] = true } if len(candidateNodes) == 0 { @@ -323,7 +323,7 @@ func fetchAttestations( continue } attestations = append(attestations, *result.attestation) - usedOwners[result.node.OwnerWallet] = true + usedOwners[result.node.Owner] = true successfulValidators++ // Stop if we have enough validators @@ -676,8 +676,8 @@ func getAntiAbuseOracle(antiAbuseOracleEndpoints []string) (node *config.Node, e if value, exists := antiAbuseOracleMap[oracleEndpoint]; exists { return &config.Node{ - DelegateOwnerWallet: value, - Endpoint: oracleEndpoint, + DelegateWallet: value, + Endpoint: oracleEndpoint, }, nil } @@ -702,8 +702,8 @@ func getAntiAbuseOracle(antiAbuseOracleEndpoints []string) (node *config.Node, e antiAbuseOracleMap[oracleEndpoint] = health.AntiAbuseWalletPubkey return &config.Node{ - DelegateOwnerWallet: health.AntiAbuseWalletPubkey, - Endpoint: oracleEndpoint, + DelegateWallet: health.AntiAbuseWalletPubkey, + Endpoint: oracleEndpoint, }, nil } @@ -814,7 +814,7 @@ func (app *ApiServer) v1ClaimRewards(c *fiber.Ctx) error { Amount: reward.Amount, Specifier: row.Specifier, RecipientEthAddress: row.Wallet.String, - ClaimAuthority: antiAbuseOracle.DelegateOwnerWallet, + ClaimAuthority: antiAbuseOracle.DelegateWallet, }, Handle: row.Handle.String, UserBank: *bankAccount, diff --git a/api/v1_claim_rewards_test.go b/api/v1_claim_rewards_test.go index 9481aa64..f40a82f9 100644 --- a/api/v1_claim_rewards_test.go +++ b/api/v1_claim_rewards_test.go @@ -81,16 +81,16 @@ func TestFetchAttestations(t *testing.T) { } allValidators := []config.Node{ - {Endpoint: validator1.URL, OwnerWallet: "0x1111111111111111111111111111111111111111"}, - {Endpoint: validator2.URL, OwnerWallet: "0x1111111111111111111111111111111111111111"}, - {Endpoint: validator3.URL, OwnerWallet: "0x3333333333333333333333333333333333333333"}, - {Endpoint: validator4.URL, OwnerWallet: "0x4444444444444444444444444444444444444444"}, - {Endpoint: validator5.URL, OwnerWallet: "0x5555555555555555555555555555555555555555"}, + {Endpoint: validator1.URL, Owner: "0x1111111111111111111111111111111111111111"}, + {Endpoint: validator2.URL, Owner: "0x1111111111111111111111111111111111111111"}, + {Endpoint: validator3.URL, Owner: "0x3333333333333333333333333333333333333333"}, + {Endpoint: validator4.URL, Owner: "0x4444444444444444444444444444444444444444"}, + {Endpoint: validator5.URL, Owner: "0x5555555555555555555555555555555555555555"}, } antiAbuseOracle := config.Node{ - Endpoint: aaoServer.URL, - DelegateOwnerWallet: "0xAAA0000000000000000000000000000000000000", + Endpoint: aaoServer.URL, + DelegateWallet: "0xAAA0000000000000000000000000000000000000", } // Set up the AAO map for the test diff --git a/api/v1_coins_post_redeem.go b/api/v1_coins_post_redeem.go index 15c30089..32e58410 100644 --- a/api/v1_coins_post_redeem.go +++ b/api/v1_coins_post_redeem.go @@ -314,7 +314,7 @@ func (app *ApiServer) v1CoinsPostRedeem(c *fiber.Ctx) error { break } if slices.ContainsFunc(existingValidatorOwners, func(s string) bool { - return strings.EqualFold(s, validator.OwnerWallet) + return strings.EqualFold(s, validator.Owner) }) { continue } diff --git a/api/v1_validators.go b/api/v1_validators.go index 151405a6..6603ebdd 100644 --- a/api/v1_validators.go +++ b/api/v1_validators.go @@ -2,10 +2,12 @@ package api import ( "context" + "strconv" "sync" "time" "api.audius.co/config" + "api.audius.co/rendezvous" "connectrpc.com/connect" ethv1 "github.com/OpenAudio/go-openaudio/pkg/api/eth/v1" "github.com/gofiber/fiber/v2" @@ -68,17 +70,17 @@ func (app *ApiServer) updateNodes(ctx context.Context) { var nodesList []config.Node for _, node := range nodes.Msg.Endpoints { - if node.ServiceType == "content-node" || node.ServiceType == "validator" { - nodesList = append(nodesList, config.Node{ - Endpoint: node.Endpoint, - DelegateOwnerWallet: node.DelegateWallet, - OwnerWallet: node.Owner, - IsStorageDisabled: false, - }) - } + nodesList = append(nodesList, config.Node{ + Id: strconv.FormatInt(node.Id, 10), + Endpoint: node.Endpoint, + DelegateWallet: node.DelegateWallet, + Owner: node.Owner, + ServiceType: node.ServiceType, + RegisteredAt: node.RegisteredAt.AsTime().Format(time.RFC3339), + }) } - app.validators.SetNodes(nodesList) + rendezvous.Refresh(nodesList) } func (app *ApiServer) v1Validators(c *fiber.Ctx) error { diff --git a/config/config.go b/config/config.go index f162d782..a92cd28a 100644 --- a/config/config.go +++ b/config/config.go @@ -23,7 +23,6 @@ type Config struct { WriteDbUrl string RunMigrations bool EsUrl string - Nodes []Node ArtistCoinRewardsStaticSenders []Node StoreAllNodes []string DeadNodes []string @@ -46,9 +45,9 @@ type Config struct { AudiusdChainID uint AudiusdEntityManagerAddress string AudiusAppUrl string - ContentNodeMonitor bool RewardCodeAuthorizedKeys []string LaunchpadDeterministicSecret string + UnsplashKeys []string } var Cfg = Config{ @@ -70,8 +69,8 @@ var Cfg = Config{ SolanaIndexerWorkers: 50, SolanaIndexerRetryInterval: 5 * time.Minute, CommsMessagePush: true, - ContentNodeMonitor: true, LaunchpadDeterministicSecret: os.Getenv("launchpadDeterministicSecret"), + UnsplashKeys: strings.Split(os.Getenv("unsplashKeys"), ","), } func init() { @@ -100,7 +99,6 @@ func init() { Cfg.DelegatePrivateKey = "13422b9affd75ff80f94f1ea394e6a6097830cb58cda2d3542f37464ecaee7df" } Cfg.AntiAbuseOracles = []string{"http://audius-discovery-provider-1"} - Cfg.Nodes = DevNodes Cfg.Rewards = core_config.MakeRewards(core_config.DevClaimAuthorities, core_config.DevRewardExtensions) Cfg.AudiusdURL = "http://audius-creator-node-1" Cfg.ChainId = "audius-devnet" @@ -123,7 +121,6 @@ func init() { log.Fatalf("Missing required %s env var: delegatePrivateKey", env) } Cfg.AntiAbuseOracles = []string{"https://discoveryprovider.staging.audius.co"} - Cfg.Nodes = StageNodes Cfg.DeadNodes = []string{} Cfg.StoreAllNodes = []string{} Cfg.UploadNodes = StageUploadNodes @@ -138,19 +135,19 @@ func init() { Cfg.VerifierAddress = "0xbbbb93A6B3A1D6fDd27909729b95CCB0cc9002C0" Cfg.ArtistCoinRewardsStaticSenders = []Node{ { - DelegateOwnerWallet: "0x140eD283b33be2145ed7d9d15f1fE7bF1E0B2Ac3", - Endpoint: "https://creatornode9.staging.audius.co", - OwnerWallet: "0x140eD283b33be2145ed7d9d15f1fE7bF1E0B2Ac3", + DelegateWallet: "0x140eD283b33be2145ed7d9d15f1fE7bF1E0B2Ac3", + Endpoint: "https://creatornode9.staging.audius.co", + Owner: "0x140eD283b33be2145ed7d9d15f1fE7bF1E0B2Ac3", }, { - DelegateOwnerWallet: "0x4c88d2c0f4c4586b41621aD6e98882ae904B98f6", - Endpoint: "https://creatornode11.staging.audius.co", - OwnerWallet: "0x4c88d2c0f4c4586b41621aD6e98882ae904B98f6", + DelegateWallet: "0x4c88d2c0f4c4586b41621aD6e98882ae904B98f6", + Endpoint: "https://creatornode11.staging.audius.co", + Owner: "0x4c88d2c0f4c4586b41621aD6e98882ae904B98f6", }, { - DelegateOwnerWallet: "0x6b52969934076318863243fb92E9C4b3A08267b5", - Endpoint: "https://creatornode12.staging.audius.co", - OwnerWallet: "0x6b52969934076318863243fb92E9C4b3A08267b5", + DelegateWallet: "0x6b52969934076318863243fb92E9C4b3A08267b5", + Endpoint: "https://creatornode12.staging.audius.co", + Owner: "0x6b52969934076318863243fb92E9C4b3A08267b5", }, } case "prod": @@ -165,7 +162,6 @@ func init() { log.Fatalf("Missing required %s env var: delegatePrivateKey", env) } Cfg.AntiAbuseOracles = []string{"https://discoveryprovider.audius.co"} - Cfg.Nodes = ProdNodes Cfg.DeadNodes = []string{ "https://content.grassfed.network", } @@ -183,24 +179,24 @@ func init() { Cfg.VerifierAddress = "0xbeef8E42e8B5964fDD2b7ca8efA0d9aef38AA996" Cfg.ArtistCoinRewardsStaticSenders = []Node{ { - DelegateOwnerWallet: "0xc8d0C29B6d540295e8fc8ac72456F2f4D41088c8", - Endpoint: "https://creatornode.audius.co", - OwnerWallet: "0xe5b256d302ea2f4e04B8F3bfD8695aDe147aB68d", + DelegateWallet: "0xc8d0C29B6d540295e8fc8ac72456F2f4D41088c8", + Endpoint: "https://creatornode.audius.co", + Owner: "0xe5b256d302ea2f4e04B8F3bfD8695aDe147aB68d", }, { - DelegateOwnerWallet: "0x159200F84c2cF000b3A014cD4D8244500CCc36ca", - Endpoint: "https://audius-cn1.tikilabs.com", - OwnerWallet: "0xe4882D9A38A2A1fc652996719AF0fb15CB968d0a", + DelegateWallet: "0x159200F84c2cF000b3A014cD4D8244500CCc36ca", + Endpoint: "https://audius-cn1.tikilabs.com", + Owner: "0xe4882D9A38A2A1fc652996719AF0fb15CB968d0a", }, { - DelegateOwnerWallet: "0x627d23D17a3eAaDB1D3823e73Ab80D474023Acab", - Endpoint: "https://audius.bragi.cc", - OwnerWallet: "0xC88C8F9a15453c7D8Ea83120Af54cc4C40EC094a", + DelegateWallet: "0x627d23D17a3eAaDB1D3823e73Ab80D474023Acab", + Endpoint: "https://audius.bragi.cc", + Owner: "0xC88C8F9a15453c7D8Ea83120Af54cc4C40EC094a", }, { - DelegateOwnerWallet: "0x422541273087beC833c57D3c15B9e17F919bFB1F", - Endpoint: "https://v.monophonic.digital", - OwnerWallet: "0x6470Daf3bd32f5014512bCdF0D02232f5640a5BD", + DelegateWallet: "0x422541273087beC833c57D3c15B9e17F919bFB1F", + Endpoint: "https://v.monophonic.digital", + Owner: "0x6470Daf3bd32f5014512bCdF0D02232f5640a5BD", }, } default: diff --git a/config/nodes.go b/config/nodes.go index cde8e4a5..2dfb806b 100644 --- a/config/nodes.go +++ b/config/nodes.go @@ -1,190 +1,21 @@ package config type Node struct { + // The unique identifier for the node + Id string // Full origin URL (including protoocol) Endpoint string // The individual wallet address for the node - DelegateOwnerWallet string + DelegateWallet string // The wallet address for the node owner/operator - OwnerWallet string + Owner string // Discovery Nodes have storage disabled - IsStorageDisabled bool + ServiceType string + // Date of registration + RegisteredAt string } var ( - ProdNodes = []Node{ - // discovery-node entries (storage disabled) - {DelegateOwnerWallet: "0x7db3789e5E2154569e802945ECF2cC92e0994841", Endpoint: "https://audius-metadata-1.figment.io", OwnerWallet: "0xc1f351FE81dFAcB3541e59177AC71Ed237BD15D0", IsStorageDisabled: true}, - {DelegateOwnerWallet: "0x67154199E79bEcd2A1f34f89d6AF962CF9863945", Endpoint: "https://dn1.matterlightblooming.xyz", OwnerWallet: "0xb5F5280e275eCa21f167d870d054b90C9C7e6669", IsStorageDisabled: true}, - {DelegateOwnerWallet: "0xd8091A289BEf13b5407082Bb66000ccA47e7e34C", Endpoint: "https://audius-discovery-9.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990", IsStorageDisabled: true}, - {DelegateOwnerWallet: "0xb4c7895739062A54F33998D65eF90afb3689d765", Endpoint: "https://discovery.grassfed.network", OwnerWallet: "0x57B1d346CDe1d2fA740F310b0d358d07d7c49547", IsStorageDisabled: true}, - {DelegateOwnerWallet: "0xE83699015c8eb793A0678eA7dC398ac58f7928c4", Endpoint: "https://audius-nodes.com", OwnerWallet: "0xE83699015c8eb793A0678eA7dC398ac58f7928c4", IsStorageDisabled: true}, - {DelegateOwnerWallet: "0x8449169096550905B903b6803FB3b64285112603", Endpoint: "https://audius-discovery-3.theblueprint.xyz", OwnerWallet: "0x68f656d19AC6d14dF209B1dd6E543b2E81d53D7B", IsStorageDisabled: true}, - {DelegateOwnerWallet: "0x048cFedf907c4C9dDD11ff882380906E78E84BbE", Endpoint: "https://blockchange-audius-discovery-03.bdnodes.net", OwnerWallet: "0x59938DF0F43DC520404e4aafDdae688a455Be870", IsStorageDisabled: true}, - {DelegateOwnerWallet: "0x16e8DF288BF5DcD507615A715A2a6155F149a865", Endpoint: "https://audius-discovery-4.theblueprint.xyz", OwnerWallet: "0x68f656d19AC6d14dF209B1dd6E543b2E81d53D7B", IsStorageDisabled: true}, - {DelegateOwnerWallet: "0xE77C7679ED77b175F935755EEb3a421635AF07EC", Endpoint: "https://audius-discovery-1.altego.net", OwnerWallet: "0xA9cB9d043d4841dE83C70556FF0Bd4949C15b5Eb", IsStorageDisabled: true}, - {DelegateOwnerWallet: "0xf7441A14A31199744Bf8e7b79405c5446C120D0f", Endpoint: "https://audius-metadata-4.figment.io", OwnerWallet: "0xc1f351FE81dFAcB3541e59177AC71Ed237BD15D0", IsStorageDisabled: true}, - {DelegateOwnerWallet: "0x2416D78b3cc41467c22578dEE7CA90450EB6526e", Endpoint: "https://blockdaemon-audius-discovery-03.bdnodes.net", OwnerWallet: "0xEe39B44cE36384157585C19df17d9B28D5637C4D", IsStorageDisabled: true}, - {DelegateOwnerWallet: "0xE019F1Ad9803cfC83e11D37Da442c9Dc8D8d82a6", Endpoint: "https://audius-metadata-3.figment.io", OwnerWallet: "0xc1f351FE81dFAcB3541e59177AC71Ed237BD15D0", IsStorageDisabled: true}, - {DelegateOwnerWallet: "0xCF3f359BfdE7bcAfE4bc058B6DFae51aBe204aB4", Endpoint: "https://audius-discovery-2.theblueprint.xyz", OwnerWallet: "0x68f656d19AC6d14dF209B1dd6E543b2E81d53D7B", IsStorageDisabled: true}, - {DelegateOwnerWallet: "0x16e8DF288BF5DcD507615A715A2a6155F149a865", Endpoint: "https://audius-discovery-4.theblueprint.xyz", OwnerWallet: "0x68f656d19AC6d14dF209B1dd6E543b2E81d53D7B", IsStorageDisabled: true}, - {DelegateOwnerWallet: "0xE77C7679ED77b175F935755EEb3a421635AF07EC", Endpoint: "https://audius-discovery-1.altego.net", OwnerWallet: "0xA9cB9d043d4841dE83C70556FF0Bd4949C15b5Eb", IsStorageDisabled: true}, - {DelegateOwnerWallet: "0xAB30eF276ADC2bE22CE58d75B4F4009173A73676", Endpoint: "https://blockchange-audius-discovery-02.bdnodes.net", OwnerWallet: "0x59938DF0F43DC520404e4aafDdae688a455Be870", IsStorageDisabled: true}, - {DelegateOwnerWallet: "0xA9cB9d043d4841dE83C70556FF0Bd4949C15b5Eb", Endpoint: "https://audius-discovery-2.altego.net", OwnerWallet: "0xA9cB9d043d4841dE83C70556FF0Bd4949C15b5Eb", IsStorageDisabled: true}, - {DelegateOwnerWallet: "0xE83699015c8eb793A0678eA7dC398ac58f7928c4", Endpoint: "https://audius-nodes.com", OwnerWallet: "0xE83699015c8eb793A0678eA7dC398ac58f7928c4", IsStorageDisabled: true}, - {DelegateOwnerWallet: "0x8464c88502925a0076c381962F8B70b6EC892861", Endpoint: "https://blockdaemon-audius-discovery-08.bdnodes.net", OwnerWallet: "0x091D2190e93A9C09f99dA05ec3F82ef5D8aa4a07", IsStorageDisabled: true}, - {DelegateOwnerWallet: "0x69cfDc1AB75384f077E4E48cf0d6483C8fB9B8A2", Endpoint: "https://audius-metadata-5.figment.io", OwnerWallet: "0x700a11aE95E34fBC769f8EAD063403987Bd0C502", IsStorageDisabled: true}, - {DelegateOwnerWallet: "0xAA29e93f4008D977078957D8f041AEAeF7e1eeBc", Endpoint: "https://dn1.stuffisup.com", OwnerWallet: "0x3E2Cd6d498b412Da182Ef25837F72355f8918BE9", IsStorageDisabled: true}, - {DelegateOwnerWallet: "0x42D35a2f33ba468fA9eB6FFEA4b975F182957556", Endpoint: "https://dn1.nodeoperator.io", OwnerWallet: "0x858e345E9DC681357ecd44bA285e04180c481fF6", IsStorageDisabled: true}, - {DelegateOwnerWallet: "0x6CAA3671162bC259094Ea4451d0d16792431C37a", Endpoint: "https://discovery-au-02.audius.openplayer.org", OwnerWallet: "0x55fc79f85eEc693A65f79DB463dc3E6831364Bce", IsStorageDisabled: true}, - {DelegateOwnerWallet: "0xbD0548Ce77e69CE22Af591A4155162A08fDDEC3d", Endpoint: "https://blockdaemon-audius-discovery-04.bdnodes.net", OwnerWallet: "0xEe39B44cE36384157585C19df17d9B28D5637C4D", IsStorageDisabled: true}, - {DelegateOwnerWallet: "0xD207D8Eb95aA5b2595cF3EEA14308EB61A36ad21", Endpoint: "https://blockchange-audius-discovery-01.bdnodes.net", OwnerWallet: "0x59938DF0F43DC520404e4aafDdae688a455Be870", IsStorageDisabled: true}, - {DelegateOwnerWallet: "0x319211E15876156BD992dd047587d0cd7b88Be77", Endpoint: "https://blockchange-audius-discovery-05.bdnodes.net", OwnerWallet: "0x59938DF0F43DC520404e4aafDdae688a455Be870", IsStorageDisabled: true}, - {DelegateOwnerWallet: "0xFD005a90cc8AF8B766F9F9cD95ee91921cC9286d", Endpoint: "https://audius-disc1.nodemagic.com", OwnerWallet: "0xf13612C7d6E31636eCC2b670d6F8a3CC50f68A48", IsStorageDisabled: true}, - {DelegateOwnerWallet: "0x5cA0d3a6590074B9fF31972824178f69e8dAB547", Endpoint: "https://audius-disc2.nodemagic.com", OwnerWallet: "0xf13612C7d6E31636eCC2b670d6F8a3CC50f68A48", IsStorageDisabled: true}, - {DelegateOwnerWallet: "0xE77C7679ED77b175F935755EEb3a421635AF07EC", Endpoint: "https://audius-discovery-1.altego.net", OwnerWallet: "0xA9cB9d043d4841dE83C70556FF0Bd4949C15b5Eb", IsStorageDisabled: true}, - {DelegateOwnerWallet: "0x57B1d346CDe1d2fA740F310b0d358d07d7c49547", Endpoint: "https://discovery.grassfed.network", OwnerWallet: "0x57B1d346CDe1d2fA740F310b0d358d07d7c49547", IsStorageDisabled: true}, - // validator entries (no storage disabled) - {DelegateOwnerWallet: "0xf686647E3737d595C60c6DE2f5F90463542FE439", Endpoint: "https://creatornode2.audius.co", OwnerWallet: "0xe5b256d302ea2f4e04B8F3bfD8695aDe147aB68d"}, - {DelegateOwnerWallet: "0x8162684B7a004AF41de09Bfd3bE6Ef53d64158F5", Endpoint: "https://audius-discovery-4.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0xB98a729444E262ec9AC5F1539b68e69aEC37Ef2C", Endpoint: "https://audius-discovery-2.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0x222f0e1eC3a08826aE8004b0aC1Dcf3334A1b0F0", Endpoint: "https://audius-discovery-16.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0xEC44A3E06241D24A872dC235bAd4EA1ACC9e0A97", Endpoint: "https://audius-discovery-11.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0x2aBFC8CA43D046181AaC6281926D710a9601EFE2", Endpoint: "https://audius-discovery-5.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0x0C32BE6328578E99b6F06E0e7A6B385EB8FC13d1", Endpoint: "https://creatornode3.audius.co", OwnerWallet: "0xe5b256d302ea2f4e04B8F3bfD8695aDe147aB68d"}, - {DelegateOwnerWallet: "0x241Da559e97d2e76f37F7144a04623849Fa576ff", Endpoint: "https://audius-discovery-10.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0xCD3eeE4f50fb35504Aed4c0Ca5841eb174428D87", Endpoint: "https://audius-discovery-17.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0xb03478a9e8fB1516AA91b272Afc7422b1c71D837", Endpoint: "https://audius-discovery-7.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0xeEB73B487f8B4b23B757d9d738Bfc48fD0cc2606", Endpoint: "https://audius-discovery-3.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0x493BC4f3E1C29B419E4C62617ecC3d0238F7AA99", Endpoint: "https://audius-discovery-14.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0x73956a079133b6fA0Ecd2777112404956E9d9272", Endpoint: "https://audius-discovery-18.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0x7DbfF3c39acC8fBb660efFBdaeA4A7172dd45ae7", Endpoint: "https://audius-discovery-12.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0x159200F84c2cF000b3A014cD4D8244500CCc36ca", Endpoint: "https://audius-cn1.tikilabs.com", OwnerWallet: "0xe4882D9A38A2A1fc652996719AF0fb15CB968d0a"}, - {DelegateOwnerWallet: "0xc8d0C29B6d540295e8fc8ac72456F2f4D41088c8", Endpoint: "https://creatornode.audius.co", OwnerWallet: "0xe5b256d302ea2f4e04B8F3bfD8695aDe147aB68d"}, - {DelegateOwnerWallet: "0xae5D0507b6653589A03ae5becb35EB0C160e7131", Endpoint: "https://audius.rickyrombo.com", OwnerWallet: "0x923EC9976bfEcFd0E8b7fEeaC9115F740f8ddB00"}, - {DelegateOwnerWallet: "0x422541273087beC833c57D3c15B9e17F919bFB1F", Endpoint: "https://v.monophonic.digital", OwnerWallet: "0x6470Daf3bd32f5014512bCdF0D02232f5640a5BD"}, - {DelegateOwnerWallet: "0x627d23D17a3eAaDB1D3823e73Ab80D474023Acab", Endpoint: "https://audius.bragi.cc", OwnerWallet: "0xC88C8F9a15453c7D8Ea83120Af54cc4C40EC094a"}, - {DelegateOwnerWallet: "0x3f0cbB987b82f620dF313A74999f025E03A11a30", Endpoint: "https://audius-discovery-1.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0x9D0a106E6cE7643DF87914c7387b3d864bfA152B", Endpoint: "https://audius-discovery-8.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0x650CE30dD821901e4790B9912fa502878Eb6E18A", Endpoint: "https://audius-discovery-6.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0x32Af5552adbCc4CbFe1C9C6B3F0117DB4CB0Cf08", Endpoint: "https://audius-discovery-15.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0xe72F2722AE881469835C0B1B16E310D4E8Afdc74", Endpoint: "https://audius-discovery-13.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - // content-node entries (no storage disabled) - {DelegateOwnerWallet: "0x6444212FFc23a4CcF7460f8Fe6D0e6074db59036", Endpoint: "https://audius-content-2.figment.io", OwnerWallet: "0xc1f351FE81dFAcB3541e59177AC71Ed237BD15D0"}, - {DelegateOwnerWallet: "0x75D2269D18C59CC2ED00a63a40367AC495E3F330", Endpoint: "https://audius-creator-13.theblueprint.xyz", OwnerWallet: "0x68f656d19AC6d14dF209B1dd6E543b2E81d53D7B"}, - {DelegateOwnerWallet: "0xBfdE9a7DD3620CB6428463E9A9e9932B4d10fdc5", Endpoint: "https://audius-content-1.figment.io", OwnerWallet: "0xc1f351FE81dFAcB3541e59177AC71Ed237BD15D0"}, - {DelegateOwnerWallet: "0x675086B880260D217963cF14F503272AEb44b2E9", Endpoint: "https://creatornode.audius.prod-eks-ap-northeast-1.staked.cloud", OwnerWallet: "0x8C860adb28CA8A33dB5571536BFCF7D6522181e5"}, - {DelegateOwnerWallet: "0x9708Fb04DeA029212126255B311a21F1F884cCB4", Endpoint: "https://audius-content-8.figment.io", OwnerWallet: "0xc1f351FE81dFAcB3541e59177AC71Ed237BD15D0"}, - {DelegateOwnerWallet: "0xECEDCaABecb40ef4bE733BA47FaD612aeA1F396F", Endpoint: "https://audius-content-3.figment.io", OwnerWallet: "0xc1f351FE81dFAcB3541e59177AC71Ed237BD15D0"}, - {DelegateOwnerWallet: "0xC9721F892BcC8822eb34237E875BE93904f11073", Endpoint: "https://audius-content-11.figment.io", OwnerWallet: "0xc1f351FE81dFAcB3541e59177AC71Ed237BD15D0"}, - {DelegateOwnerWallet: "0x3Db0E61591063310eEd22fd57E6f7F1ab2Bb538E", Endpoint: "https://audius-content-6.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0x00B1CA1A34257860f66e742eF163Ad30bF42d075", Endpoint: "https://blockdaemon-audius-content-07.bdnodes.net", OwnerWallet: "0x447E3572B5511cc6ea0700e34D2443017D081d7e"}, - {DelegateOwnerWallet: "0x4Ad694B3fC34b3cC245aF6AA7B43C52ddD0d7AAE", Endpoint: "https://blockdaemon-audius-content-02.bdnodes.net", OwnerWallet: "0x091D2190e93A9C09f99dA05ec3F82ef5D8aa4a07"}, - {DelegateOwnerWallet: "0x10fF8197f2e94eF880d940D2414E0A14983c3bFE", Endpoint: "https://audius-content-5.figment.io", OwnerWallet: "0xc1f351FE81dFAcB3541e59177AC71Ed237BD15D0"}, - {DelegateOwnerWallet: "0x5e0D0BeDC11F0B512457f6f707A35703b1447Fb5", Endpoint: "https://blockchange-audius-content-02.bdnodes.net", OwnerWallet: "0x59938DF0F43DC520404e4aafDdae688a455Be870"}, - {DelegateOwnerWallet: "0x780641e157621621658F118375dc1B36Ea514d46", Endpoint: "https://audius-content-12.figment.io", OwnerWallet: "0x700a11aE95E34fBC769f8EAD063403987Bd0C502"}, - {DelegateOwnerWallet: "0x2fE2652296c40BB22D33C6379558Bf63A25b4f9a", Endpoint: "https://audius-content-15.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0x817c513C1B702eA0BdD4F8C1204C60372f715006", Endpoint: "https://audius-content-14.figment.io", OwnerWallet: "0xc1f351FE81dFAcB3541e59177AC71Ed237BD15D0"}, - {DelegateOwnerWallet: "0x33a2da466B14990E0124383204b06F9196f62d8e", Endpoint: "https://audius-content-13.figment.io", OwnerWallet: "0xc1f351FE81dFAcB3541e59177AC71Ed237BD15D0"}, - {DelegateOwnerWallet: "0x65Fe5BEf65A0E0b0520d6beE7767ea6Da7f792f6", Endpoint: "https://audius-creator-5.theblueprint.xyz", OwnerWallet: "0x68f656d19AC6d14dF209B1dd6E543b2E81d53D7B"}, - {DelegateOwnerWallet: "0xe0b56BAe2276E016d3DB314Dd7374e596B0457ac", Endpoint: "https://creatornode.audius3.prod-eks-ap-northeast-1.staked.cloud", OwnerWallet: "0x8C860adb28CA8A33dB5571536BFCF7D6522181e5"}, - {DelegateOwnerWallet: "0xCbDa351492e52fdb2f0E7FBc440cA2047738b71C", Endpoint: "https://audius-content-14.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0x0E0aF7035581C615d07372be16D99A9B64E5B2e9", Endpoint: "https://audius-creator-1.theblueprint.xyz", OwnerWallet: "0x68f656d19AC6d14dF209B1dd6E543b2E81d53D7B"}, - {DelegateOwnerWallet: "0x8ea81225013719950E968DE0602c4Eca458fA9f4", Endpoint: "https://blockdaemon-audius-content-03.bdnodes.net", OwnerWallet: "0x091D2190e93A9C09f99dA05ec3F82ef5D8aa4a07"}, - {DelegateOwnerWallet: "0xcfFA8ACF0b04d9278eEE13928be264b2E9aaab97", Endpoint: "https://blockdaemon-audius-content-04.bdnodes.net", OwnerWallet: "0xEe39B44cE36384157585C19df17d9B28D5637C4D"}, - {DelegateOwnerWallet: "0xB4Ff0cab630FB05a7fcEfec9E979a968b8f4fE55", Endpoint: "https://blockdaemon-audius-content-05.bdnodes.net", OwnerWallet: "0xEe39B44cE36384157585C19df17d9B28D5637C4D"}, - {DelegateOwnerWallet: "0x7449da7d1548C11c481b87667EC9b2A8F20C13A0", Endpoint: "https://blockdaemon-audius-content-06.bdnodes.net", OwnerWallet: "0xEe39B44cE36384157585C19df17d9B28D5637C4D"}, - {DelegateOwnerWallet: "0x16650eDB44C720ea627d5a59ff0b4f74c37fe419", Endpoint: "https://blockdaemon-audius-content-08.bdnodes.net", OwnerWallet: "0x447E3572B5511cc6ea0700e34D2443017D081d7e"}, - {DelegateOwnerWallet: "0xD5Cfcf4149c683516239fc653D5a470F3F4A606D", Endpoint: "https://blockdaemon-audius-content-09.bdnodes.net", OwnerWallet: "0x447E3572B5511cc6ea0700e34D2443017D081d7e"}, - {DelegateOwnerWallet: "0xff753331CEa586DD5B23bd21222a3c902909F2dd", Endpoint: "https://audius-content-10.figment.io", OwnerWallet: "0xc1f351FE81dFAcB3541e59177AC71Ed237BD15D0"}, - {DelegateOwnerWallet: "0xCEb6a23d6132Cfe329b3c8E3c45f9DDc28A62Bd4", Endpoint: "https://audius-content-1.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0x2e9e7A4e35C3136fB651a0dBF8f91c9f5C27BBf7", Endpoint: "https://audius-content-2.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0x742da6cAc2782FeA961bB7B9150a048F5167D1e1", Endpoint: "https://audius-content-3.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0xcbb0cE7481685587b0988195Ff0cD6AA1A701657", Endpoint: "https://audius-content-4.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0xFec4708155277D35d568aD6Ca322262577683584", Endpoint: "https://audius-content-5.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0x3Db0E61591063310eEd22fd57E6f7F1ab2Bb538E", Endpoint: "https://audius-content-6.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0xE6C00e7E8d582fD2856718a5439f1aeEB68e27E5", Endpoint: "https://audius-content-7.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0x5e0D0BeDC11F0B512457f6f707A35703b1447Fb5", Endpoint: "https://blockchange-audius-content-02.bdnodes.net", OwnerWallet: "0x59938DF0F43DC520404e4aafDdae688a455Be870"}, - {DelegateOwnerWallet: "0xe3F1c416c3919bB2ffD78F1e38b9E81E8c80815F", Endpoint: "https://blockchange-audius-content-03.bdnodes.net", OwnerWallet: "0x59938DF0F43DC520404e4aafDdae688a455Be870"}, - {DelegateOwnerWallet: "0xB6f506557B2e9026743FeA6157e52F204D26690F", Endpoint: "https://audius-content-9.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0x2AF4598D3CF95D8e76987c02BC8A8D71F58d49d5", Endpoint: "https://audius-content-10.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0xB2684Cca5281d2bA6D9Ce66Cca215635FF2Ba466", Endpoint: "https://audius-content-11.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0x28924C99822eA08bFCeDdE3a411308633948b349", Endpoint: "https://audius-content-12.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0xcb23908aa0dCDef762ebEaA38391D8fFC69E6e8F", Endpoint: "https://audius-content-13.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0x28924C99822eA08bFCeDdE3a411308633948b349", Endpoint: "https://audius-content-12.cultur3stake.com", OwnerWallet: "0x2168990Cd51c7C7DdE4b16Ac4fe7dbA269768990"}, - {DelegateOwnerWallet: "0x69e749266C59757dA81F8C659Be6B07ce5Bac6C9", Endpoint: "https://cn4.mainnet.audiusindex.org", OwnerWallet: "0x528D6Fe7dF9356C8EabEC850B0f908F53075B382"}, - {DelegateOwnerWallet: "0x720758adEa33433833c14e2516fA421261D0875e", Endpoint: "https://audius-creator-7.theblueprint.xyz", OwnerWallet: "0x68f656d19AC6d14dF209B1dd6E543b2E81d53D7B"}, - {DelegateOwnerWallet: "0x44955AD360652c302644F564B42D1458C584A4ec", Endpoint: "https://cn1.shakespearetech.com", OwnerWallet: "0x45FC5529a17f0c5285173Ad08359C53Fa8a674b4"}, - {DelegateOwnerWallet: "0x68835714d9c208f9d6F4953F0555507e492fd898", Endpoint: "https://cn2.shakespearetech.com", OwnerWallet: "0x45FC5529a17f0c5285173Ad08359C53Fa8a674b4"}, - {DelegateOwnerWallet: "0x7162Ee2b7F0cB9651fd2FA2838B0CAF225B2a8D3", Endpoint: "https://cn3.shakespearetech.com", OwnerWallet: "0x45FC5529a17f0c5285173Ad08359C53Fa8a674b4"}, - {DelegateOwnerWallet: "0x078842E88B82e6a69549043269AE3aADD5581105", Endpoint: "https://audius-creator-8.theblueprint.xyz", OwnerWallet: "0x68f656d19AC6d14dF209B1dd6E543b2E81d53D7B"}, - {DelegateOwnerWallet: "0x2DfC8152eF49e91b83638ad2bd0D2F9efC6f65b5", Endpoint: "https://audius-creator-9.theblueprint.xyz", OwnerWallet: "0x68f656d19AC6d14dF209B1dd6E543b2E81d53D7B"}, - {DelegateOwnerWallet: "0x97BcBFA8289731d694440795094E831599Ab7A11", Endpoint: "https://audius-creator-10.theblueprint.xyz", OwnerWallet: "0x68f656d19AC6d14dF209B1dd6E543b2E81d53D7B"}, - {DelegateOwnerWallet: "0xfe38c5Ea3579c9333fE302414fe1895F7a320beF", Endpoint: "https://audius-creator-11.theblueprint.xyz", OwnerWallet: "0x68f656d19AC6d14dF209B1dd6E543b2E81d53D7B"}, - {DelegateOwnerWallet: "0x8C78ef541135e2cb037f91109fb8EE780fa4709d", Endpoint: "https://audius-creator-12.theblueprint.xyz", OwnerWallet: "0x68f656d19AC6d14dF209B1dd6E543b2E81d53D7B"}, - } - StageNodes = []Node{ - { - DelegateOwnerWallet: "0x8fcFA10Bd3808570987dbb5B1EF4AB74400FbfDA", - Endpoint: "https://discoveryprovider.staging.audius.co", - OwnerWallet: "0x8fcFA10Bd3808570987dbb5B1EF4AB74400FbfDA", - IsStorageDisabled: true, - }, - { - DelegateOwnerWallet: "0xDC2BDF1F23381CA2eC9e9c70D4FD96CD8645D090", - Endpoint: "https://creatornode5.staging.audius.co", - OwnerWallet: "0xf7C96916bd37Ad76D4EEDd6536B81c29706C8056", - }, - { - DelegateOwnerWallet: "0x68039d001D87E7A5E6B06fe0825EA7871C1Cd6C2", - Endpoint: "https://creatornode6.staging.audius.co", - OwnerWallet: "0xf7C96916bd37Ad76D4EEDd6536B81c29706C8056", - }, - { - DelegateOwnerWallet: "0x1F8e7aF58086992Ef4c4fc0371446974BBbC0D9F", - Endpoint: "https://creatornode7.staging.audius.co", - OwnerWallet: "0x5E98cBEEAA2aCEDEc0833AC3D1634E2A7aE0f3c2", - }, - { - DelegateOwnerWallet: "0x140eD283b33be2145ed7d9d15f1fE7bF1E0B2Ac3", - Endpoint: "https://creatornode9.staging.audius.co", - OwnerWallet: "0x5E98cBEEAA2aCEDEc0833AC3D1634E2A7aE0f3c2", - }, - { - DelegateOwnerWallet: "0x4c88d2c0f4c4586b41621aD6e98882ae904B98f6", - Endpoint: "https://creatornode11.staging.audius.co", - OwnerWallet: "0x5E98cBEEAA2aCEDEc0833AC3D1634E2A7aE0f3c2", - }, - { - DelegateOwnerWallet: "0x6b52969934076318863243fb92E9C4b3A08267b5", - Endpoint: "https://creatornode12.staging.audius.co", - OwnerWallet: "0x5E98cBEEAA2aCEDEc0833AC3D1634E2A7aE0f3c2", - }, - } - DevNodes = []Node{ - { - DelegateOwnerWallet: "0x73EB6d82CFB20bA669e9c178b718d770C49BB52f", - Endpoint: "http://audius-discovery-provider-1", - OwnerWallet: "0x73EB6d82CFB20bA669e9c178b718d770C49BB52f", - IsStorageDisabled: true, - }, - { - DelegateOwnerWallet: "0x0D38e653eC28bdea5A2296fD5940aaB2D0B8875c", - Endpoint: "http://audius-creator-node-1", - OwnerWallet: "0x0D38e653eC28bdea5A2296fD5940aaB2D0B8875c", - }, - { - DelegateOwnerWallet: "0x1B569e8f1246907518Ff3386D523dcF373e769B6", - Endpoint: "http://audius-creator-node-2", - OwnerWallet: "0x1B569e8f1246907518Ff3386D523dcF373e769B6", - }, - { - DelegateOwnerWallet: "0xCBB025e7933FADfc7C830AE520Fb2FD6D28c1065", - Endpoint: "http://audius-creator-node-3", - OwnerWallet: "0xCBB025e7933FADfc7C830AE520Fb2FD6D28c1065", - }, - } - ProdUploadNodes = []string{ "https://creatornode.audius.co", "https://creatornode2.audius.co", diff --git a/rendezvous/rendezvous.go b/rendezvous/rendezvous.go index 72dcc882..abaa5f1c 100644 --- a/rendezvous/rendezvous.go +++ b/rendezvous/rendezvous.go @@ -18,13 +18,7 @@ import ( var GlobalHasher *RendezvousHasher func init() { - hosts := make([]string, len(config.Cfg.Nodes)) - for i, node := range config.Cfg.Nodes { - if !node.IsStorageDisabled { - hosts[i] = node.Endpoint - } - } - GlobalHasher = NewRendezvousHasher(hosts) + GlobalHasher = NewRendezvousHasher([]string{}) } type HostTuple struct { @@ -44,6 +38,14 @@ func (s HostTuples) Less(i, j int) bool { return c == -1 } +func Refresh(nodes []config.Node) { + hosts := make([]string, len(nodes)) + for i, node := range nodes { + hosts[i] = node.Endpoint + } + GlobalHasher = NewRendezvousHasher(hosts) +} + func NewRendezvousHasher(hosts []string) *RendezvousHasher { deadHosts := strings.Join(config.Cfg.DeadNodes, ",") liveHosts := make([]string, 0, len(hosts)) From 04755796839ae40924174280795c23c57ac22f85 Mon Sep 17 00:00:00 2001 From: Raymond Jacobson Date: Tue, 16 Dec 2025 16:09:12 -0800 Subject: [PATCH 2/3] Cleanup and add shuffle --- api/content_nodes.go | 16 ++++++++++------ api/discovery_nodes.go | 16 ++++++++++------ api/server.go | 4 ++++ api/v1_validators.go | 1 + config/nodes.go | 2 ++ 5 files changed, 27 insertions(+), 12 deletions(-) diff --git a/api/content_nodes.go b/api/content_nodes.go index f3f525fa..cc02fc93 100644 --- a/api/content_nodes.go +++ b/api/content_nodes.go @@ -1,6 +1,7 @@ package api import ( + "math/rand" "strings" "github.com/gofiber/fiber/v2" @@ -11,15 +12,18 @@ func (app *ApiServer) contentNodes(c *fiber.Ctx) error { for _, node := range app.validators.GetNodes() { if node.ServiceType == "content-node" { contentNodes = append(contentNodes, fiber.Map{ - "id": node.Id, - "owner": node.Owner, - "endpoint": node.Endpoint, - "delegateWallet": node.DelegateWallet, - "serviceType": node.ServiceType, - "registeredAt": node.RegisteredAt, + "spID": node.Id, + "owner": node.Owner, + "endpoint": node.Endpoint, + "delegateOwnerWallet": node.DelegateWallet, + "type": node.ServiceType, + "blockNumber": node.BlockNumber, }) } } + rand.Shuffle(len(contentNodes), func(i, j int) { + contentNodes[i], contentNodes[j] = contentNodes[j], contentNodes[i] + }) if strings.HasSuffix(c.Path(), "/verbose") { return c.JSON(fiber.Map{ diff --git a/api/discovery_nodes.go b/api/discovery_nodes.go index ed94e894..59740c15 100644 --- a/api/discovery_nodes.go +++ b/api/discovery_nodes.go @@ -1,6 +1,7 @@ package api import ( + "math/rand" "strings" "github.com/gofiber/fiber/v2" @@ -11,15 +12,18 @@ func (app *ApiServer) discoveryNodes(c *fiber.Ctx) error { for _, node := range app.validators.GetNodes() { if node.ServiceType == "discovery-node" { discoveryNodes = append(discoveryNodes, fiber.Map{ - "id": node.Id, - "owner": node.Owner, - "endpoint": node.Endpoint, - "delegateWallet": node.DelegateWallet, - "serviceType": node.ServiceType, - "registeredAt": node.RegisteredAt, + "spID": node.Id, + "owner": node.Owner, + "endpoint": node.Endpoint, + "delegateOwnerWallet": node.DelegateWallet, + "type": node.ServiceType, + "blockNumber": node.BlockNumber, }) } } + rand.Shuffle(len(discoveryNodes), func(i, j int) { + discoveryNodes[i], discoveryNodes[j] = discoveryNodes[j], discoveryNodes[i] + }) if strings.HasSuffix(c.Path(), "/verbose") { return c.JSON(fiber.Map{ diff --git a/api/server.go b/api/server.go index 5d628aa0..58880a25 100644 --- a/api/server.go +++ b/api/server.go @@ -584,9 +584,13 @@ func NewApiServer(config config.Config) *ApiServer { // Nodes app.Get("/validators", app.v1Validators) app.Get("/discovery", app.discoveryNodes) + app.Get("/discovery-nodes", app.discoveryNodes) app.Get("/discovery/verbose", app.discoveryNodes) + app.Get("/discovery-nodes/verbose", app.discoveryNodes) app.Get("/content", app.contentNodes) + app.Get("/content-nodes", app.contentNodes) app.Get("/content/verbose", app.contentNodes) + app.Get("/content-nodes/verbose", app.contentNodes) // Unsplash proxy app.All("/unsplash/*", app.unsplash) diff --git a/api/v1_validators.go b/api/v1_validators.go index 6603ebdd..0a878505 100644 --- a/api/v1_validators.go +++ b/api/v1_validators.go @@ -77,6 +77,7 @@ func (app *ApiServer) updateNodes(ctx context.Context) { Owner: node.Owner, ServiceType: node.ServiceType, RegisteredAt: node.RegisteredAt.AsTime().Format(time.RFC3339), + BlockNumber: node.BlockNumber, }) } app.validators.SetNodes(nodesList) diff --git a/config/nodes.go b/config/nodes.go index 2dfb806b..bfcf6b74 100644 --- a/config/nodes.go +++ b/config/nodes.go @@ -13,6 +13,8 @@ type Node struct { ServiceType string // Date of registration RegisteredAt string + // Block number of registration + BlockNumber int64 } var ( From 36989b39f87adb6d9b561f3d71e08f73875aebea Mon Sep 17 00:00:00 2001 From: Raymond Jacobson Date: Tue, 16 Dec 2025 17:41:39 -0800 Subject: [PATCH 3/3] Comments --- api/server.go | 2 +- config/nodes.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/server.go b/api/server.go index 58880a25..12dc4cfb 100644 --- a/api/server.go +++ b/api/server.go @@ -676,7 +676,7 @@ func (app *ApiServer) home(c *fiber.Ctx) error { "started": app.started, "uptime": time.Since(app.started).Truncate(time.Second).String(), "data": []string{ - "https://discoveryprovider.audius.co", + "https://api.audius.co", }, }) } diff --git a/config/nodes.go b/config/nodes.go index bfcf6b74..83f86027 100644 --- a/config/nodes.go +++ b/config/nodes.go @@ -9,7 +9,7 @@ type Node struct { DelegateWallet string // The wallet address for the node owner/operator Owner string - // Discovery Nodes have storage disabled + // Service type (discovery-node, content-node, validator) ServiceType string // Date of registration RegisteredAt string