diff options
Diffstat (limited to 'main')
| -rw-r--r-- | main/cashu.c | 8 | ||||
| -rw-r--r-- | main/cashu.h | 3 | ||||
| -rw-r--r-- | main/config.c | 10 | ||||
| -rw-r--r-- | main/config.h | 2 | ||||
| -rw-r--r-- | main/session.c | 30 | ||||
| -rw-r--r-- | main/session.h | 7 | ||||
| -rw-r--r-- | main/tollgate_api.c | 36 |
7 files changed, 87 insertions, 9 deletions
diff --git a/main/cashu.c b/main/cashu.c index ba6d9ef..ec0566c 100644 --- a/main/cashu.c +++ b/main/cashu.c | |||
| @@ -255,6 +255,14 @@ uint64_t cashu_calculate_allotment_ms(uint64_t token_amount, uint64_t price_per_ | |||
| 255 | return (token_amount / price_per_step) * step_size_ms; | 255 | return (token_amount / price_per_step) * step_size_ms; |
| 256 | } | 256 | } |
| 257 | 257 | ||
| 258 | uint64_t cashu_calculate_allotment(uint64_t token_amount, uint64_t price_per_step, | ||
| 259 | const char *metric, uint64_t step_size) | ||
| 260 | { | ||
| 261 | if (price_per_step == 0) return 0; | ||
| 262 | (void)metric; | ||
| 263 | return (token_amount / price_per_step) * step_size; | ||
| 264 | } | ||
| 265 | |||
| 258 | bool cashu_is_mint_accepted(const char *mint_url) | 266 | bool cashu_is_mint_accepted(const char *mint_url) |
| 259 | { | 267 | { |
| 260 | if (!mint_url || mint_url[0] == '\0') return false; | 268 | if (!mint_url || mint_url[0] == '\0') return false; |
diff --git a/main/cashu.h b/main/cashu.h index 4c3d43b..76ad2eb 100644 --- a/main/cashu.h +++ b/main/cashu.h | |||
| @@ -37,6 +37,9 @@ esp_err_t cashu_check_proof_states(const char *mint_url, const cashu_token_t *to | |||
| 37 | uint64_t cashu_calculate_allotment_ms(uint64_t token_amount, uint64_t price_per_step, | 37 | uint64_t cashu_calculate_allotment_ms(uint64_t token_amount, uint64_t price_per_step, |
| 38 | uint64_t step_size_ms); | 38 | uint64_t step_size_ms); |
| 39 | 39 | ||
| 40 | uint64_t cashu_calculate_allotment(uint64_t token_amount, uint64_t price_per_step, | ||
| 41 | const char *metric, uint64_t step_size); | ||
| 42 | |||
| 40 | bool cashu_is_mint_accepted(const char *mint_url); | 43 | bool cashu_is_mint_accepted(const char *mint_url); |
| 41 | 44 | ||
| 42 | #endif | 45 | #endif |
diff --git a/main/config.c b/main/config.c index 9257397..3e01efc 100644 --- a/main/config.c +++ b/main/config.c | |||
| @@ -20,6 +20,8 @@ esp_err_t tollgate_config_init(void) | |||
| 20 | g_config.ap_max_conn = 4; | 20 | g_config.ap_max_conn = 4; |
| 21 | g_config.price_per_step = 21; | 21 | g_config.price_per_step = 21; |
| 22 | g_config.step_size_ms = 60000; | 22 | g_config.step_size_ms = 60000; |
| 23 | g_config.step_size_bytes = 22020096; | ||
| 24 | strncpy(g_config.metric, "bytes", sizeof(g_config.metric) - 1); | ||
| 23 | g_config.persist_threshold_sats = 1; | 25 | g_config.persist_threshold_sats = 1; |
| 24 | g_config.nostr_publish_interval_s = 21600; | 26 | g_config.nostr_publish_interval_s = 21600; |
| 25 | g_config.client_enabled = false; | 27 | g_config.client_enabled = false; |
| @@ -136,6 +138,14 @@ esp_err_t tollgate_config_init(void) | |||
| 136 | cJSON *step = cJSON_GetObjectItem(root, "step_size_ms"); | 138 | cJSON *step = cJSON_GetObjectItem(root, "step_size_ms"); |
| 137 | if (step) g_config.step_size_ms = step->valueint; | 139 | if (step) g_config.step_size_ms = step->valueint; |
| 138 | 140 | ||
| 141 | cJSON *step_bytes = cJSON_GetObjectItem(root, "step_size_bytes"); | ||
| 142 | if (step_bytes) g_config.step_size_bytes = step_bytes->valueint; | ||
| 143 | |||
| 144 | cJSON *metric = cJSON_GetObjectItem(root, "metric"); | ||
| 145 | if (metric && cJSON_IsString(metric)) { | ||
| 146 | strncpy(g_config.metric, metric->valuestring, sizeof(g_config.metric) - 1); | ||
| 147 | } | ||
| 148 | |||
| 139 | cJSON *persist = cJSON_GetObjectItem(root, "persist_threshold_sats"); | 149 | cJSON *persist = cJSON_GetObjectItem(root, "persist_threshold_sats"); |
| 140 | if (persist) g_config.persist_threshold_sats = (uint64_t)persist->valuedouble; | 150 | if (persist) g_config.persist_threshold_sats = (uint64_t)persist->valuedouble; |
| 141 | 151 | ||
diff --git a/main/config.h b/main/config.h index de9f856..86b5e1a 100644 --- a/main/config.h +++ b/main/config.h | |||
| @@ -43,6 +43,8 @@ typedef struct { | |||
| 43 | char lnurl_url[256]; | 43 | char lnurl_url[256]; |
| 44 | int price_per_step; | 44 | int price_per_step; |
| 45 | int step_size_ms; | 45 | int step_size_ms; |
| 46 | int step_size_bytes; | ||
| 47 | char metric[16]; | ||
| 46 | uint64_t persist_threshold_sats; | 48 | uint64_t persist_threshold_sats; |
| 47 | 49 | ||
| 48 | char nostr_geohash[16]; | 50 | char nostr_geohash[16]; |
diff --git a/main/session.c b/main/session.c index 521b74a..4854163 100644 --- a/main/session.c +++ b/main/session.c | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | #include "session.h" | 1 | #include "session.h" |
| 2 | #include "firewall.h" | 2 | #include "firewall.h" |
| 3 | #include "dns_server.h" | 3 | #include "dns_server.h" |
| 4 | #include "config.h" | ||
| 4 | #include "esp_log.h" | 5 | #include "esp_log.h" |
| 5 | #include "freertos/FreeRTOS.h" | 6 | #include "freertos/FreeRTOS.h" |
| 6 | #include "freertos/task.h" | 7 | #include "freertos/task.h" |
| @@ -103,6 +104,29 @@ session_t *session_create(uint32_t client_ip, uint64_t allotment_ms, | |||
| 103 | return NULL; | 104 | return NULL; |
| 104 | } | 105 | } |
| 105 | 106 | ||
| 107 | session_t *session_create_bytes(uint32_t client_ip, uint64_t allotment_bytes, | ||
| 108 | const char *spent_secrets[], int secret_count) | ||
| 109 | { | ||
| 110 | session_t *s = session_create(client_ip, 0, spent_secrets, secret_count); | ||
| 111 | if (s) { | ||
| 112 | s->allotment_bytes = allotment_bytes; | ||
| 113 | s->bytes_consumed = 0; | ||
| 114 | s->allotment_ms = INT64_MAX; | ||
| 115 | esp_ip4_addr_t ip = { .addr = client_ip }; | ||
| 116 | ESP_LOGI(TAG, "Bytes session created: " IPSTR " allotment=%llu bytes", IP2STR(&ip), | ||
| 117 | (unsigned long long)allotment_bytes); | ||
| 118 | } | ||
| 119 | return s; | ||
| 120 | } | ||
| 121 | |||
| 122 | void session_add_bytes(uint32_t client_ip, uint64_t bytes) | ||
| 123 | { | ||
| 124 | session_t *s = session_find_by_ip(client_ip); | ||
| 125 | if (s && s->active) { | ||
| 126 | s->bytes_consumed += bytes; | ||
| 127 | } | ||
| 128 | } | ||
| 129 | |||
| 106 | session_t *session_find_by_ip(uint32_t client_ip) | 130 | session_t *session_find_by_ip(uint32_t client_ip) |
| 107 | { | 131 | { |
| 108 | for (int i = 0; i < SESSION_MAX_CLIENTS; i++) { | 132 | for (int i = 0; i < SESSION_MAX_CLIENTS; i++) { |
| @@ -136,6 +160,12 @@ void session_extend(session_t *session, uint64_t additional_ms) | |||
| 136 | bool session_is_expired(const session_t *session) | 160 | bool session_is_expired(const session_t *session) |
| 137 | { | 161 | { |
| 138 | if (!session || !session->active) return true; | 162 | if (!session || !session->active) return true; |
| 163 | |||
| 164 | const tollgate_config_t *cfg = tollgate_config_get(); | ||
| 165 | if (cfg && strcmp(cfg->metric, "bytes") == 0) { | ||
| 166 | return session->bytes_consumed >= session->allotment_bytes; | ||
| 167 | } | ||
| 168 | |||
| 139 | int64_t elapsed = get_time_ms() - session->start_time_ms; | 169 | int64_t elapsed = get_time_ms() - session->start_time_ms; |
| 140 | return elapsed >= (int64_t)session->allotment_ms; | 170 | return elapsed >= (int64_t)session->allotment_ms; |
| 141 | } | 171 | } |
diff --git a/main/session.h b/main/session.h index 8e2d48d..6282f5a 100644 --- a/main/session.h +++ b/main/session.h | |||
| @@ -13,6 +13,8 @@ typedef struct { | |||
| 13 | char mac[SESSION_MAX_MAC_LEN]; | 13 | char mac[SESSION_MAX_MAC_LEN]; |
| 14 | uint64_t allotment_ms; | 14 | uint64_t allotment_ms; |
| 15 | int64_t start_time_ms; | 15 | int64_t start_time_ms; |
| 16 | uint64_t allotment_bytes; | ||
| 17 | uint64_t bytes_consumed; | ||
| 16 | bool active; | 18 | bool active; |
| 17 | char spent_secrets[5][65]; | 19 | char spent_secrets[5][65]; |
| 18 | int spent_secret_count; | 20 | int spent_secret_count; |
| @@ -23,6 +25,11 @@ esp_err_t session_manager_init(void); | |||
| 23 | session_t *session_create(uint32_t client_ip, uint64_t allotment_ms, | 25 | session_t *session_create(uint32_t client_ip, uint64_t allotment_ms, |
| 24 | const char *spent_secrets[], int secret_count); | 26 | const char *spent_secrets[], int secret_count); |
| 25 | 27 | ||
| 28 | session_t *session_create_bytes(uint32_t client_ip, uint64_t allotment_bytes, | ||
| 29 | const char *spent_secrets[], int secret_count); | ||
| 30 | |||
| 31 | void session_add_bytes(uint32_t client_ip, uint64_t bytes); | ||
| 32 | |||
| 26 | session_t *session_find_by_ip(uint32_t client_ip); | 33 | session_t *session_find_by_ip(uint32_t client_ip); |
| 27 | session_t *session_find_by_mac(const char *mac); | 34 | session_t *session_find_by_mac(const char *mac); |
| 28 | 35 | ||
diff --git a/main/tollgate_api.c b/main/tollgate_api.c index 72ed726..25e7dd2 100644 --- a/main/tollgate_api.c +++ b/main/tollgate_api.c | |||
| @@ -78,7 +78,8 @@ static cJSON *create_session_event(uint32_t client_ip, uint64_t allotment_ms) | |||
| 78 | 78 | ||
| 79 | cJSON *metric_tag = cJSON_CreateArray(); | 79 | cJSON *metric_tag = cJSON_CreateArray(); |
| 80 | cJSON_AddItemToArray(metric_tag, cJSON_CreateString("metric")); | 80 | cJSON_AddItemToArray(metric_tag, cJSON_CreateString("metric")); |
| 81 | cJSON_AddItemToArray(metric_tag, cJSON_CreateString("milliseconds")); | 81 | const tollgate_config_t *mcfg = tollgate_config_get(); |
| 82 | cJSON_AddItemToArray(metric_tag, cJSON_CreateString(mcfg->metric[0] ? mcfg->metric : "milliseconds")); | ||
| 82 | cJSON_AddItemToArray(tags, metric_tag); | 83 | cJSON_AddItemToArray(tags, metric_tag); |
| 83 | 84 | ||
| 84 | cJSON_AddItemToObject(root, "tags", tags); | 85 | cJSON_AddItemToObject(root, "tags", tags); |
| @@ -98,13 +99,14 @@ static esp_err_t api_get_discovery(httpd_req_t *req) | |||
| 98 | 99 | ||
| 99 | cJSON *metric_tag = cJSON_CreateArray(); | 100 | cJSON *metric_tag = cJSON_CreateArray(); |
| 100 | cJSON_AddItemToArray(metric_tag, cJSON_CreateString("metric")); | 101 | cJSON_AddItemToArray(metric_tag, cJSON_CreateString("metric")); |
| 101 | cJSON_AddItemToArray(metric_tag, cJSON_CreateString("milliseconds")); | 102 | cJSON_AddItemToArray(metric_tag, cJSON_CreateString(cfg->metric[0] ? cfg->metric : "milliseconds")); |
| 102 | cJSON_AddItemToArray(tags, metric_tag); | 103 | cJSON_AddItemToArray(tags, metric_tag); |
| 103 | 104 | ||
| 104 | cJSON *step_tag = cJSON_CreateArray(); | 105 | cJSON *step_tag = cJSON_CreateArray(); |
| 105 | cJSON_AddItemToArray(step_tag, cJSON_CreateString("step_size")); | 106 | cJSON_AddItemToArray(step_tag, cJSON_CreateString("step_size")); |
| 106 | char step_str[32]; | 107 | char step_str[32]; |
| 107 | snprintf(step_str, sizeof(step_str), "%d", cfg->step_size_ms); | 108 | bool is_bytes = (strcmp(cfg->metric, "bytes") == 0); |
| 109 | snprintf(step_str, sizeof(step_str), "%d", is_bytes ? cfg->step_size_bytes : cfg->step_size_ms); | ||
| 108 | cJSON_AddItemToArray(step_tag, cJSON_CreateString(step_str)); | 110 | cJSON_AddItemToArray(step_tag, cJSON_CreateString(step_str)); |
| 109 | cJSON_AddItemToArray(tags, step_tag); | 111 | cJSON_AddItemToArray(tags, step_tag); |
| 110 | 112 | ||
| @@ -280,7 +282,10 @@ static esp_err_t api_post_payment(httpd_req_t *req) | |||
| 280 | } | 282 | } |
| 281 | 283 | ||
| 282 | const tollgate_config_t *cfg = tollgate_config_get(); | 284 | const tollgate_config_t *cfg = tollgate_config_get(); |
| 283 | uint64_t allotment = cashu_calculate_allotment_ms(token->total_amount, cfg->price_per_step, cfg->step_size_ms); | 285 | bool is_bytes = (strcmp(cfg->metric, "bytes") == 0); |
| 286 | uint64_t step_size = is_bytes ? (uint64_t)cfg->step_size_bytes : (uint64_t)cfg->step_size_ms; | ||
| 287 | uint64_t allotment = cashu_calculate_allotment(token->total_amount, cfg->price_per_step, | ||
| 288 | cfg->metric, step_size); | ||
| 284 | if (allotment == 0) { | 289 | if (allotment == 0) { |
| 285 | free(states); | 290 | free(states); |
| 286 | free(token); | 291 | free(token); |
| @@ -299,7 +304,12 @@ static esp_err_t api_post_payment(httpd_req_t *req) | |||
| 299 | for (int i = 0; i < secret_count; i++) { | 304 | for (int i = 0; i < secret_count; i++) { |
| 300 | secrets[i] = token->proofs[i].secret; | 305 | secrets[i] = token->proofs[i].secret; |
| 301 | } | 306 | } |
| 302 | session_t *session = session_create(client_ip, allotment, secrets, secret_count); | 307 | session_t *session; |
| 308 | if (is_bytes) { | ||
| 309 | session = session_create_bytes(client_ip, allotment, secrets, secret_count); | ||
| 310 | } else { | ||
| 311 | session = session_create(client_ip, allotment, secrets, secret_count); | ||
| 312 | } | ||
| 303 | if (!session) { | 313 | if (!session) { |
| 304 | free(states); | 314 | free(states); |
| 305 | free(token); | 315 | free(token); |
| @@ -339,12 +349,20 @@ static esp_err_t api_get_usage(httpd_req_t *req) | |||
| 339 | return ESP_OK; | 349 | return ESP_OK; |
| 340 | } | 350 | } |
| 341 | 351 | ||
| 342 | int64_t elapsed = (int64_t)xTaskGetTickCount() * portTICK_PERIOD_MS - session->start_time_ms; | 352 | const tollgate_config_t *cfg = tollgate_config_get(); |
| 343 | int64_t remaining = session->allotment_ms - elapsed; | 353 | bool is_bytes = (strcmp(cfg->metric, "bytes") == 0); |
| 344 | if (remaining < 0) remaining = 0; | ||
| 345 | 354 | ||
| 346 | char resp[64]; | 355 | char resp[64]; |
| 347 | snprintf(resp, sizeof(resp), "%lld/%llu", (long long)remaining, (unsigned long long)session->allotment_ms); | 356 | if (is_bytes) { |
| 357 | int64_t remaining = (int64_t)session->allotment_bytes - (int64_t)session->bytes_consumed; | ||
| 358 | if (remaining < 0) remaining = 0; | ||
| 359 | snprintf(resp, sizeof(resp), "%lld/%llu", (long long)remaining, (unsigned long long)session->allotment_bytes); | ||
| 360 | } else { | ||
| 361 | int64_t elapsed = (int64_t)xTaskGetTickCount() * portTICK_PERIOD_MS - session->start_time_ms; | ||
| 362 | int64_t remaining = session->allotment_ms - elapsed; | ||
| 363 | if (remaining < 0) remaining = 0; | ||
| 364 | snprintf(resp, sizeof(resp), "%lld/%llu", (long long)remaining, (unsigned long long)session->allotment_ms); | ||
| 365 | } | ||
| 348 | httpd_resp_set_type(req, "text/plain"); | 366 | httpd_resp_set_type(req, "text/plain"); |
| 349 | httpd_resp_send(req, resp, strlen(resp)); | 367 | httpd_resp_send(req, resp, strlen(resp)); |
| 350 | return ESP_OK; | 368 | return ESP_OK; |