diff options
| author | Your Name <you@example.com> | 2026-05-22 03:48:46 +0530 |
|---|---|---|
| committer | Your Name <you@example.com> | 2026-05-22 03:48:46 +0530 |
| commit | ed06f7eeab28c1fa6242c4ea6c3b9c933661fc06 (patch) | |
| tree | 96230dd069102688318f73b60b8322255ea30cad /main/cvm_server.c | |
| parent | 7009d2e0ac346376733863966374eac296e0471e (diff) | |
feat(cvm): fix CVM MCP roundtrip - task creation, subscription, relay selection
- Move CVM server start before mint_health_start (avoids RAM fragmentation)
- Fix NIP-01 subscription: #p tag must be array not string
- Fix read loop: tolerate TLS timeouts, don't disconnect
- Reduce TLS timeout from 15s to 5s for faster event delivery
- Add WS frame logging for debugging
- Sign test events with board's nsec (--sec flag) for owner auth
- Change default CVM relay to nos.lol (forwards ephemeral kind 25910)
- MCP get_config and get_balance roundtrips confirmed working
- Unit tests pass (16/16)
Diffstat (limited to 'main/cvm_server.c')
| -rw-r--r-- | main/cvm_server.c | 64 |
1 files changed, 39 insertions, 25 deletions
diff --git a/main/cvm_server.c b/main/cvm_server.c index f3a5ab8..1ac5cb6 100644 --- a/main/cvm_server.c +++ b/main/cvm_server.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include "esp_tls.h" | 12 | #include "esp_tls.h" |
| 13 | #include "esp_crt_bundle.h" | 13 | #include "esp_crt_bundle.h" |
| 14 | #include "esp_random.h" | 14 | #include "esp_random.h" |
| 15 | #include "esp_heap_caps.h" | ||
| 15 | #include "freertos/FreeRTOS.h" | 16 | #include "freertos/FreeRTOS.h" |
| 16 | #include "freertos/task.h" | 17 | #include "freertos/task.h" |
| 17 | #include <string.h> | 18 | #include <string.h> |
| @@ -150,7 +151,7 @@ static esp_err_t ws_connect(const char *relay_url, esp_tls_t **tls_out) | |||
| 150 | 151 | ||
| 151 | esp_tls_cfg_t tls_cfg = { | 152 | esp_tls_cfg_t tls_cfg = { |
| 152 | .crt_bundle_attach = esp_crt_bundle_attach, | 153 | .crt_bundle_attach = esp_crt_bundle_attach, |
| 153 | .timeout_ms = 15000, | 154 | .timeout_ms = 5000, |
| 154 | }; | 155 | }; |
| 155 | esp_tls_t *tls = esp_tls_init(); | 156 | esp_tls_t *tls = esp_tls_init(); |
| 156 | if (!tls) return ESP_ERR_NO_MEM; | 157 | if (!tls) return ESP_ERR_NO_MEM; |
| @@ -507,7 +508,9 @@ static esp_err_t subscribe_to_relay(esp_tls_t *tls, const char *npub) | |||
| 507 | cJSON *kinds = cJSON_CreateArray(); | 508 | cJSON *kinds = cJSON_CreateArray(); |
| 508 | cJSON_AddItemToArray(kinds, cJSON_CreateNumber(25910)); | 509 | cJSON_AddItemToArray(kinds, cJSON_CreateNumber(25910)); |
| 509 | cJSON_AddItemToObject(filter, "kinds", kinds); | 510 | cJSON_AddItemToObject(filter, "kinds", kinds); |
| 510 | cJSON_AddStringToObject(filter, "#p", npub); | 511 | cJSON *p_tag = cJSON_CreateArray(); |
| 512 | cJSON_AddItemToArray(p_tag, cJSON_CreateString(npub)); | ||
| 513 | cJSON_AddItemToObject(filter, "#p", p_tag); | ||
| 511 | cJSON_AddNumberToObject(filter, "limit", 100); | 514 | cJSON_AddNumberToObject(filter, "limit", 100); |
| 512 | cJSON_AddItemToArray(sub, filter); | 515 | cJSON_AddItemToArray(sub, filter); |
| 513 | 516 | ||
| @@ -556,33 +559,33 @@ static void cvm_relay_task(void *arg) | |||
| 556 | } | 559 | } |
| 557 | 560 | ||
| 558 | int64_t last_ping_time = (int64_t)(xTaskGetTickCount() * portTICK_PERIOD_MS) / 1000; | 561 | int64_t last_ping_time = (int64_t)(xTaskGetTickCount() * portTICK_PERIOD_MS) / 1000; |
| 559 | int consecutive_timeouts = 0; | ||
| 560 | while (g_running) { | 562 | while (g_running) { |
| 561 | int rlen = esp_tls_conn_read(tls, buf, CVM_WS_BUF_SIZE - 1); | 563 | int rlen = esp_tls_conn_read(tls, buf, CVM_WS_BUF_SIZE - 1); |
| 562 | if (rlen < 0) { | ||
| 563 | ESP_LOGW(TAG, "Read error on %s (rlen=%d)", relay_url, rlen); | ||
| 564 | break; | ||
| 565 | } | ||
| 566 | if (rlen == 0) { | 564 | if (rlen == 0) { |
| 565 | ESP_LOGW(TAG, "Connection closed by relay"); | ||
| 567 | break; | 566 | break; |
| 568 | } else { | 567 | } |
| 569 | consecutive_timeouts = 0; | 568 | if (rlen < 0) { |
| 570 | if ((buf[0] & 0x0F) == 0x01) { | 569 | vTaskDelay(pdMS_TO_TICKS(100)); |
| 571 | char *text = parse_ws_text_frame(buf, rlen); | 570 | continue; |
| 572 | if (text) { | 571 | } |
| 573 | if (strlen(text) > 0) { | 572 | |
| 574 | process_relay_message(relay_url, text); | 573 | ESP_LOGI(TAG, "WS frame received: %d bytes, opcode=0x%02x", rlen, buf[0] & 0x0F); |
| 575 | } | 574 | |
| 576 | free(text); | 575 | if ((buf[0] & 0x0F) == 0x01) { |
| 576 | char *text = parse_ws_text_frame(buf, rlen); | ||
| 577 | if (text) { | ||
| 578 | if (strlen(text) > 0) { | ||
| 579 | process_relay_message(relay_url, text); | ||
| 577 | } | 580 | } |
| 578 | } else if ((buf[0] & 0x0F) == 0x09) { | 581 | free(text); |
| 579 | ESP_LOGD(TAG, "Relay ping received, sending pong"); | ||
| 580 | uint8_t pong[2] = {0x8A, 0x00}; | ||
| 581 | esp_tls_conn_write(tls, pong, 2); | ||
| 582 | } else if ((buf[0] & 0x0F) == 0x08) { | ||
| 583 | ESP_LOGW(TAG, "Relay sent close frame"); | ||
| 584 | break; | ||
| 585 | } | 582 | } |
| 583 | } else if ((buf[0] & 0x0F) == 0x09) { | ||
| 584 | uint8_t pong[2] = {0x8A, 0x00}; | ||
| 585 | esp_tls_conn_write(tls, pong, 2); | ||
| 586 | } else if ((buf[0] & 0x0F) == 0x08) { | ||
| 587 | ESP_LOGW(TAG, "Relay sent close frame"); | ||
| 588 | break; | ||
| 586 | } | 589 | } |
| 587 | 590 | ||
| 588 | int64_t now = (int64_t)(xTaskGetTickCount() * portTICK_PERIOD_MS) / 1000; | 591 | int64_t now = (int64_t)(xTaskGetTickCount() * portTICK_PERIOD_MS) / 1000; |
| @@ -590,7 +593,6 @@ static void cvm_relay_task(void *arg) | |||
| 590 | uint8_t ping[2] = {0x89, 0x00}; | 593 | uint8_t ping[2] = {0x89, 0x00}; |
| 591 | esp_tls_conn_write(tls, ping, 2); | 594 | esp_tls_conn_write(tls, ping, 2); |
| 592 | last_ping_time = now; | 595 | last_ping_time = now; |
| 593 | ESP_LOGD(TAG, "Sent WS keepalive ping"); | ||
| 594 | } | 596 | } |
| 595 | } | 597 | } |
| 596 | 598 | ||
| @@ -726,8 +728,20 @@ void cvm_server_start(void) | |||
| 726 | const tollgate_config_t *cfg = tollgate_config_get(); | 728 | const tollgate_config_t *cfg = tollgate_config_get(); |
| 727 | const char *relay = (cfg->cvm_relays[0]) ? cfg->cvm_relays : "wss://relay.primal.net"; | 729 | const char *relay = (cfg->cvm_relays[0]) ? cfg->cvm_relays : "wss://relay.primal.net"; |
| 728 | 730 | ||
| 731 | ESP_LOGI(TAG, "Starting CVM relay task (free internal: %u, largest: %u)", | ||
| 732 | heap_caps_get_free_size(MALLOC_CAP_INTERNAL), | ||
| 733 | heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL)); | ||
| 734 | |||
| 729 | char *relay_copy = strdup(relay); | 735 | char *relay_copy = strdup(relay); |
| 730 | xTaskCreate(cvm_relay_task, "cvm_relay", 16384, relay_copy, 5, &g_task); | 736 | BaseType_t ret = xTaskCreatePinnedToCore(cvm_relay_task, "cvm_relay", 16384, relay_copy, 5, &g_task, 1); |
| 737 | if (ret != pdPASS) { | ||
| 738 | ESP_LOGE(TAG, "Failed to create cvm_relay task (ret=%d, free internal: %u)", | ||
| 739 | ret, heap_caps_get_free_size(MALLOC_CAP_INTERNAL)); | ||
| 740 | g_running = false; | ||
| 741 | free(relay_copy); | ||
| 742 | return; | ||
| 743 | } | ||
| 744 | ESP_LOGI(TAG, "CVM relay task created on core %d", xPortGetCoreID()); | ||
| 731 | } | 745 | } |
| 732 | 746 | ||
| 733 | void cvm_server_stop(void) | 747 | void cvm_server_stop(void) |