diff --git a/src/lib/block_notify.cpp b/src/lib/block_notify.cpp index 60b3034..4c32a2a 100644 --- a/src/lib/block_notify.cpp +++ b/src/lib/block_notify.cpp @@ -1,186 +1,146 @@ #include "block_notify.hpp" -#include "led_handler.hpp" -char *wsServer; -esp_websocket_client_handle_t blockNotifyClient = NULL; -uint32_t currentBlockHeight = 873400; -uint16_t blockMedianFee = 1; -bool blockNotifyInit = false; -unsigned long int lastBlockUpdate; +// Initialize static members +WebSocketsClient BlockNotify::webSocket; +uint32_t BlockNotify::currentBlockHeight = 878000; +uint16_t BlockNotify::blockMedianFee = 1; +bool BlockNotify::notifyInit = false; +unsigned long int BlockNotify::lastBlockUpdate = 0; +TaskHandle_t BlockNotify::taskHandle = nullptr; -const char *mempoolWsCert = R"EOF( ------BEGIN CERTIFICATE----- -MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB -iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl -cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV -BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw -MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV -BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU -aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy -dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK -AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B -3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY -tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ -Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 -VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT -79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 -c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT -Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l -c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee -UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE -Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd -BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G -A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF -Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO -VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 -ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs -8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR -iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze -Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ -XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ -qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB -VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB -L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG -jjxDah2nGN59PRbxYvnKkKj9 ------END CERTIFICATE----- -)EOF"; - -void setupBlockNotify() +void BlockNotify::taskNotify(void* pvParameters) { - IPAddress result; - - int dnsErr = -1; - String mempoolInstance = - preferences.getString("mempoolInstance", DEFAULT_MEMPOOL_INSTANCE); - - while (dnsErr != 1 && !strchr(mempoolInstance.c_str(), ':')) - { - dnsErr = WiFi.hostByName(mempoolInstance.c_str(), result); - - if (dnsErr != 1) + for (;;) { - Serial.print(mempoolInstance); - Serial.println(F("mempool DNS could not be resolved")); - WiFi.reconnect(); - vTaskDelay(pdMS_TO_TICKS(1000)); + webSocket.loop(); + vTaskDelay(10 / portTICK_PERIOD_MS); } - } - - // Get current block height through regular API - int blockFetch = getBlockFetch(); - - if (blockFetch > currentBlockHeight) - currentBlockHeight = blockFetch; - - if (currentBlockHeight != -1) - { - lastBlockUpdate = esp_timer_get_time() / 1000000; - } - - if (workQueue != nullptr) - { - WorkItem blockUpdate = {TASK_BLOCK_UPDATE, 0}; - xQueueSend(workQueue, &blockUpdate, portMAX_DELAY); - } - - // std::strcpy(wsServer, String("wss://" + mempoolInstance + - // "/api/v1/ws").c_str()); - - const String protocol = preferences.getBool("mempoolSecure", DEFAULT_MEMPOOL_SECURE) ? "wss" : "ws"; - - String mempoolUri = protocol + "://" + preferences.getString("mempoolInstance", DEFAULT_MEMPOOL_INSTANCE) + "/api/v1/ws"; - - esp_websocket_client_config_t config = { - // .uri = "wss://mempool.space/api/v1/ws", - .task_stack = (6*1024), - .user_agent = USER_AGENT - }; - - if (preferences.getBool("mempoolSecure", DEFAULT_MEMPOOL_SECURE)) { - config.cert_pem = mempoolWsCert; - } - - config.uri = mempoolUri.c_str(); - - Serial.printf("Connecting to %s\r\n", preferences.getString("mempoolInstance", DEFAULT_MEMPOOL_INSTANCE)); - - blockNotifyClient = esp_websocket_client_init(&config); - esp_websocket_register_events(blockNotifyClient, WEBSOCKET_EVENT_ANY, - onWebsocketBlockEvent, blockNotifyClient); - esp_websocket_client_start(blockNotifyClient); } -void onWebsocketBlockEvent(void *handler_args, esp_event_base_t base, - int32_t event_id, void *event_data) +void BlockNotify::setupTask() { - esp_websocket_event_data_t *data = (esp_websocket_event_data_t *)event_data; - const String sub = "{\"action\": \"want\", \"data\":[\"blocks\", \"mempool-blocks\"]}"; - switch (event_id) - { - case WEBSOCKET_EVENT_CONNECTED: - blockNotifyInit = true; + xTaskCreate(taskNotify, "blockNotify", (6 * 1024), NULL, tskIDLE_PRIORITY, + &taskHandle); +} - Serial.println(F("Connected to Mempool.space WebSocket")); +void BlockNotify::onWebsocketEvent(WStype_t type, uint8_t* payload, size_t length) { + switch(type) { + case WStype_DISCONNECTED: { + Serial.println(F("Mempool.space WS Connection Closed")); + break; + } + case WStype_CONNECTED: { + notifyInit = true; + Serial.print(F("Connected to ")); + Serial.println(preferences.getString("mempoolInstance", DEFAULT_MEMPOOL_INSTANCE)); - Serial.println(sub); - if (esp_websocket_client_send_text(blockNotifyClient, sub.c_str(), - sub.length(), portMAX_DELAY) == -1) + JsonDocument doc; + doc["action"] = "want"; + JsonArray data = doc.createNestedArray("data"); + data.add("blocks"); + data.add("mempool-blocks"); + + String sub; + serializeJson(doc, sub); + Serial.println(sub); + webSocket.sendTXT(sub.c_str()); + break; + } + case WStype_TEXT: { + JsonDocument doc; + JsonDocument filter; + filter["block"]["height"] = true; + filter["mempool-blocks"][0]["medianFee"] = true; + + deserializeJson(doc, (char*)payload, DeserializationOption::Filter(filter)); + + if (debugLogEnabled()) { + Serial.println(doc.as()); + } + + if (doc["block"].is()) + { + JsonObject block = doc["block"]; + if (block["height"].as() != currentBlockHeight) { + BlockNotify::getInstance().processNewBlock(block["height"].as()); + } + } + else if (doc["mempool-blocks"].is()) + { + JsonArray blockInfo = doc["mempool-blocks"].as(); + uint medianFee = (uint)round(blockInfo[0]["medianFee"].as()); + BlockNotify::getInstance().processNewBlockFee(medianFee); + } + break; + } + case WStype_BIN: + case WStype_ERROR: + case WStype_FRAGMENT_TEXT_START: + case WStype_FRAGMENT_BIN_START: + case WStype_FRAGMENT: + case WStype_PING: + case WStype_PONG: + case WStype_FRAGMENT_FIN: { + break; + } + } +} + +void BlockNotify::setup() +{ + IPAddress result; + int dnsErr = -1; + String mempoolInstance = preferences.getString("mempoolInstance", DEFAULT_MEMPOOL_INSTANCE); + + while (dnsErr != 1 && !strchr(mempoolInstance.c_str(), ':')) { - Serial.println(F("Mempool.space WS Block Subscribe Error")); + dnsErr = WiFi.hostByName(mempoolInstance.c_str(), result); + + if (dnsErr != 1) + { + Serial.print(mempoolInstance); + Serial.println(F("mempool DNS could not be resolved")); + WiFi.reconnect(); + vTaskDelay(pdMS_TO_TICKS(1000)); + } } - break; - case WEBSOCKET_EVENT_DATA: - onWebsocketBlockMessage(data); - break; - case WEBSOCKET_EVENT_ERROR: - Serial.println(F("Mempool.space WS Connnection error")); - break; - case WEBSOCKET_EVENT_DISCONNECTED: - Serial.println(F("Mempool.space WS Connnection Closed")); - break; - } -} + // Get current block height through regular API + int blockFetch = fetchLatestBlock(); -void onWebsocketBlockMessage(esp_websocket_event_data_t *event_data) -{ - JsonDocument doc; + if (blockFetch > currentBlockHeight) + currentBlockHeight = blockFetch; - JsonDocument filter; - filter["block"]["height"] = true; - filter["mempool-blocks"][0]["medianFee"] = true; - - deserializeJson(doc, (char *)event_data->data_ptr, DeserializationOption::Filter(filter)); - - // if (error) { - // Serial.print("deserializeJson() failed: "); - // Serial.println(error.c_str()); - // return; - // } - - if (doc["block"].is()) - { - JsonObject block = doc["block"]; - - if (block["height"].as() == currentBlockHeight) { - return; + if (currentBlockHeight != -1) + { + lastBlockUpdate = esp_timer_get_time() / 1000000; } - processNewBlock(block["height"].as()); - } - else if (doc["mempool-blocks"].is()) - { - JsonArray blockInfo = doc["mempool-blocks"].as(); + if (workQueue != nullptr) + { + WorkItem blockUpdate = {TASK_BLOCK_UPDATE, 0}; + xQueueSend(workQueue, &blockUpdate, portMAX_DELAY); + } - uint medianFee = (uint)round(blockInfo[0]["medianFee"].as()); + const bool useSSL = preferences.getBool("mempoolSecure", DEFAULT_MEMPOOL_SECURE); + const int port = useSSL ? 443 : 80; - processNewBlockFee(medianFee); - } + if (useSSL) { + webSocket.beginSSL(mempoolInstance.c_str(), port, "/api/v1/ws"); +// webSocket.beginSSL("ws.btclock.dev", port, "/api/v1/ws"); - doc.clear(); + } else { + webSocket.begin(mempoolInstance.c_str(), port, "/api/v1/ws"); + } + + webSocket.onEvent(onWebsocketEvent); + webSocket.setReconnectInterval(5000); + webSocket.enableHeartbeat(15000, 3000, 2); + + setupTask(); } -void processNewBlock(uint32_t newBlockHeight) { +void BlockNotify::processNewBlock(uint32_t newBlockHeight) { if (newBlockHeight <= currentBlockHeight) { return; @@ -220,76 +180,65 @@ void processNewBlock(uint32_t newBlockHeight) { } } -void processNewBlockFee(uint16_t newBlockFee) { - if (blockMedianFee == newBlockFee) +void BlockNotify::processNewBlockFee(uint16_t newBlockFee) { + if (blockMedianFee == newBlockFee) { - return; + return; } - // Serial.printf("New median fee: %d\r\n", medianFee); blockMedianFee = newBlockFee; if (workQueue != nullptr) { - WorkItem blockUpdate = {TASK_FEE_UPDATE, 0}; - xQueueSend(workQueue, &blockUpdate, portMAX_DELAY); + WorkItem blockUpdate = {TASK_FEE_UPDATE, 0}; + xQueueSend(workQueue, &blockUpdate, portMAX_DELAY); } } -uint32_t getBlockHeight() { return currentBlockHeight; } - -void setBlockHeight(uint32_t newBlockHeight) -{ - currentBlockHeight = newBlockHeight; +uint32_t BlockNotify::getBlockHeight() const { + return currentBlockHeight; } -uint16_t getBlockMedianFee() { return blockMedianFee; } - -void setBlockMedianFee(uint16_t newBlockMedianFee) +void BlockNotify::setBlockHeight(uint32_t newBlockHeight) { - blockMedianFee = newBlockMedianFee; + currentBlockHeight = newBlockHeight; } -bool isBlockNotifyConnected() -{ - if (blockNotifyClient == NULL) - return false; - return esp_websocket_client_is_connected(blockNotifyClient); +uint16_t BlockNotify::getBlockMedianFee() const { + return blockMedianFee; } -bool getBlockNotifyInit() +void BlockNotify::setBlockMedianFee(uint16_t newBlockMedianFee) { - return blockNotifyInit; + blockMedianFee = newBlockMedianFee; } -void stopBlockNotify() +bool BlockNotify::isConnected() const { - if (blockNotifyClient == NULL) - return; - - esp_websocket_client_close(blockNotifyClient, pdMS_TO_TICKS(5000)); - esp_websocket_client_stop(blockNotifyClient); - esp_websocket_client_destroy(blockNotifyClient); - - blockNotifyClient = NULL; + return webSocket.isConnected(); } -void restartBlockNotify() +bool BlockNotify::isInitialized() const { - stopBlockNotify(); - - if (blockNotifyClient == NULL) { - setupBlockNotify(); - return; - } - - // esp_websocket_client_close(blockNotifyClient, pdMS_TO_TICKS(5000)); - // esp_websocket_client_stop(blockNotifyClient); - // esp_websocket_client_start(blockNotifyClient); + return notifyInit; } +void BlockNotify::stop() +{ + webSocket.disconnect(); + if (taskHandle != NULL) { + vTaskDelete(taskHandle); + taskHandle = NULL; + } +} -int getBlockFetch() { +void BlockNotify::restart() +{ + stop(); + setup(); +} + +int BlockNotify::fetchLatestBlock() { try { String mempoolInstance = preferences.getString("mempoolInstance", DEFAULT_MEMPOOL_INSTANCE); const String protocol = preferences.getBool("mempoolSecure", DEFAULT_MEMPOOL_SECURE) ? "https" : "http"; @@ -312,12 +261,12 @@ int getBlockFetch() { return 2203; // B-T-C } -uint getLastBlockUpdate() +uint BlockNotify::getLastBlockUpdate() const { - return lastBlockUpdate; + return lastBlockUpdate; } -void setLastBlockUpdate(uint lastUpdate) +void BlockNotify::setLastBlockUpdate(uint lastUpdate) { - lastBlockUpdate = lastUpdate; + lastBlockUpdate = lastUpdate; } \ No newline at end of file diff --git a/src/lib/block_notify.hpp b/src/lib/block_notify.hpp index 9c41bf0..aa99f2b 100644 --- a/src/lib/block_notify.hpp +++ b/src/lib/block_notify.hpp @@ -4,8 +4,7 @@ #include #include #include -#include - +#include #include #include @@ -14,28 +13,54 @@ #include "lib/timers.hpp" #include "lib/shared.hpp" -// using namespace websockets; +class BlockNotify { +public: + static BlockNotify& getInstance() { + static BlockNotify instance; + return instance; + } -void setupBlockNotify(); + // Delete copy constructor and assignment operator + BlockNotify(const BlockNotify&) = delete; + void operator=(const BlockNotify&) = delete; -void onWebsocketBlockEvent(void *handler_args, esp_event_base_t base, - int32_t event_id, void *event_data); -void onWebsocketBlockMessage(esp_websocket_event_data_t *event_data); + // Block notification setup and control + void setup(); + void stop(); + void restart(); + bool isConnected() const; + bool isInitialized() const; -void setBlockHeight(uint32_t newBlockHeight); -uint32_t getBlockHeight(); + // Block height management + void setBlockHeight(uint32_t newBlockHeight); + uint32_t getBlockHeight() const; -void setBlockMedianFee(uint16_t blockMedianFee); -uint16_t getBlockMedianFee(); + // Block fee management + void setBlockMedianFee(uint16_t blockMedianFee); + uint16_t getBlockMedianFee() const; -bool isBlockNotifyConnected(); -void stopBlockNotify(); -void restartBlockNotify(); + // Block processing + void processNewBlock(uint32_t newBlockHeight); + void processNewBlockFee(uint16_t newBlockFee); -void processNewBlock(uint32_t newBlockHeight); -void processNewBlockFee(uint16_t newBlockFee); + // Block fetch and update tracking + int fetchLatestBlock(); + uint getLastBlockUpdate() const; + void setLastBlockUpdate(uint lastUpdate); -bool getBlockNotifyInit(); -uint32_t getLastBlockUpdate(); -int getBlockFetch(); -void setLastBlockUpdate(uint32_t lastUpdate); + // Task handling + static void taskNotify(void* pvParameters); + +private: + BlockNotify() = default; // Private constructor for singleton + + void setupTask(); + static void onWebsocketEvent(WStype_t type, uint8_t* payload, size_t length); + + static WebSocketsClient webSocket; + static uint32_t currentBlockHeight; + static uint16_t blockMedianFee; + static bool notifyInit; + static unsigned long int lastBlockUpdate; + static TaskHandle_t taskHandle; +}; \ No newline at end of file diff --git a/src/lib/config.cpp b/src/lib/config.cpp index 6354a7a..def33ea 100644 --- a/src/lib/config.cpp +++ b/src/lib/config.cpp @@ -265,7 +265,7 @@ void setupPreferences() EPDManager::getInstance().setForegroundColor(preferences.getUInt("fgColor", DEFAULT_FG_COLOR)); EPDManager::getInstance().setBackgroundColor(preferences.getUInt("bgColor", DEFAULT_BG_COLOR)); - setBlockHeight(preferences.getUInt("blockHeight", INITIAL_BLOCK_HEIGHT)); + BlockNotify::getInstance().setBlockHeight(preferences.getUInt("blockHeight", INITIAL_BLOCK_HEIGHT)); setPrice(preferences.getUInt("lastPrice", INITIAL_LAST_PRICE), CURRENCY_USD); if (!preferences.isKey("enableDebugLog")) { @@ -373,7 +373,7 @@ void setupWebsocketClients(void *pvParameters) } else if (dataSource == THIRD_PARTY_SOURCE) { - setupBlockNotify(); + BlockNotify::getInstance().setup(); setupPriceNotify(); } diff --git a/src/lib/nostr_notify.cpp b/src/lib/nostr_notify.cpp index 6d9cce9..7df5ea1 100644 --- a/src/lib/nostr_notify.cpp +++ b/src/lib/nostr_notify.cpp @@ -79,8 +79,9 @@ void nostrTask(void *pvParameters) { DataSourceType dataSource = getDataSource(); if(dataSource == NOSTR_SOURCE) { - int blockFetch = getBlockFetch(); - processNewBlock(blockFetch); + auto& blockNotify = BlockNotify::getInstance(); + int blockFetch = blockNotify.fetchLatestBlock(); + blockNotify.processNewBlock(blockFetch); } while (1) @@ -174,11 +175,13 @@ void handleNostrEventCallback(const String &subId, nostr::SignedNostrEvent *even processNewPrice(obj["content"].as(), CURRENCY_USD); } else if (typeValue == "blockHeight") { - processNewBlock(obj["content"].as()); + auto& blockNotify = BlockNotify::getInstance(); + blockNotify.processNewBlock(obj["content"].as()); } if (medianFee != 0) { - processNewBlockFee(medianFee); + auto& blockNotify = BlockNotify::getInstance(); + blockNotify.processNewBlockFee(medianFee); } } } diff --git a/src/lib/ota.cpp b/src/lib/ota.cpp index 59497c7..2d94d48 100644 --- a/src/lib/ota.cpp +++ b/src/lib/ota.cpp @@ -74,8 +74,8 @@ void onOTAStart() ButtonHandler::suspendTask(); // stopWebServer(); - stopBlockNotify(); - stopPriceNotify(); + auto& blockNotify = BlockNotify::getInstance(); + blockNotify.stop(); } void handleOTATask(void *parameter) diff --git a/src/lib/screen_handler.cpp b/src/lib/screen_handler.cpp index 6b3241e..75e59aa 100644 --- a/src/lib/screen_handler.cpp +++ b/src/lib/screen_handler.cpp @@ -251,9 +251,8 @@ void workerTask(void *pvParameters) { } else if (currentScreenValue == SCREEN_SATS_PER_CURRENCY) { taskEpdContent = parseSatsPerCurrency(price, currency, preferences.getBool("useSatsSymbol", DEFAULT_USE_SATS_SYMBOL)); } else { - taskEpdContent = - parseMarketCap(getBlockHeight(), price, currency, - preferences.getBool("mcapBigChar", DEFAULT_MCAP_BIG_CHAR)); + auto& blockNotify = BlockNotify::getInstance(); + taskEpdContent = parseMarketCap(blockNotify.getBlockHeight(), price, currency, preferences.getBool("mcapBigChar", DEFAULT_MCAP_BIG_CHAR)); } EPDManager::getInstance().setContent(taskEpdContent); @@ -261,16 +260,19 @@ void workerTask(void *pvParameters) { } case TASK_FEE_UPDATE: { if (currentScreenValue == SCREEN_BLOCK_FEE_RATE) { - taskEpdContent = parseBlockFees(static_cast(getBlockMedianFee())); + auto& blockNotify = BlockNotify::getInstance(); + taskEpdContent = parseBlockFees(static_cast(blockNotify.getBlockMedianFee())); EPDManager::getInstance().setContent(taskEpdContent); } break; } case TASK_BLOCK_UPDATE: { if (currentScreenValue != SCREEN_HALVING_COUNTDOWN) { - taskEpdContent = parseBlockHeight(getBlockHeight()); + auto& blockNotify = BlockNotify::getInstance(); + taskEpdContent = parseBlockHeight(blockNotify.getBlockHeight()); } else { - taskEpdContent = parseHalvingCountdown(getBlockHeight(), preferences.getBool("useBlkCountdown", DEFAULT_USE_BLOCK_COUNTDOWN)); + auto& blockNotify = BlockNotify::getInstance(); + taskEpdContent = parseHalvingCountdown(blockNotify.getBlockHeight(), preferences.getBool("useBlkCountdown", DEFAULT_USE_BLOCK_COUNTDOWN)); } if (currentScreenValue == SCREEN_HALVING_COUNTDOWN || diff --git a/src/lib/v2_notify.cpp b/src/lib/v2_notify.cpp index 6d9fc61..a8174a1 100644 --- a/src/lib/v2_notify.cpp +++ b/src/lib/v2_notify.cpp @@ -131,7 +131,7 @@ namespace V2Notify { uint newBlockHeight = doc["blockheight"].as(); - if (newBlockHeight == getBlockHeight()) + if (newBlockHeight == BlockNotify::getInstance().getBlockHeight()) { return; } @@ -140,7 +140,7 @@ namespace V2Notify Serial.print(F("processNewBlock ")); Serial.println(newBlockHeight); } - processNewBlock(newBlockHeight); + BlockNotify::getInstance().processNewBlock(newBlockHeight); } else if (doc["blockfee"].is()) { @@ -151,7 +151,7 @@ namespace V2Notify Serial.println(medianFee); } - processNewBlockFee(medianFee); + BlockNotify::getInstance().processNewBlockFee(medianFee); } else if (doc["price"].is()) { diff --git a/src/lib/webserver.cpp b/src/lib/webserver.cpp index 1d6a878..430828d 100644 --- a/src/lib/webserver.cpp +++ b/src/lib/webserver.cpp @@ -247,7 +247,8 @@ JsonDocument getStatusObject() JsonObject conStatus = root["connectionStatus"].to(); conStatus["price"] = isPriceNotifyConnected(); - conStatus["blocks"] = isBlockNotifyConnected(); + auto& blockNotify = BlockNotify::getInstance(); + conStatus["blocks"] = blockNotify.isConnected(); conStatus["V2"] = V2Notify::isV2NotifyConnected(); conStatus["nostr"] = nostrConnected(); @@ -906,7 +907,7 @@ void onApiStopDataSources(AsyncWebServerRequest *request) request->beginResponseStream(JSON_CONTENT); stopPriceNotify(); - stopBlockNotify(); + BlockNotify::getInstance().stop(); request->send(response); } @@ -917,9 +918,7 @@ void onApiRestartDataSources(AsyncWebServerRequest *request) request->beginResponseStream(JSON_CONTENT); restartPriceNotify(); - restartBlockNotify(); - // setupPriceNotify(); - // setupBlockNotify(); + BlockNotify::getInstance().restart(); request->send(response); } diff --git a/src/main.cpp b/src/main.cpp index c892a03..08d38ad 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -19,6 +19,7 @@ #include "ESPAsyncWebServer.h" #include "lib/config.hpp" #include "lib/led_handler.hpp" +#include "lib/block_notify.hpp" uint wifiLostConnection; uint priceNotifyLostConnection = 0; @@ -49,7 +50,8 @@ void handleBlockNotifyDisconnection() { if ((getUptime() - blockNotifyLostConnection) > 300) { // 5 minutes timeout Serial.println(F("Block notification connection lost for 5 minutes, restarting handler...")); - restartBlockNotify(); + auto& blockNotify = BlockNotify::getInstance(); + blockNotify.restart(); blockNotifyLostConnection = 0; } } @@ -92,13 +94,14 @@ void checkWiFiConnection() { void checkMissedBlocks() { Serial.println(F("Long time (45 min) since last block, checking if I missed anything...")); - int currentBlock = getBlockFetch(); + auto& blockNotify = BlockNotify::getInstance(); + int currentBlock = blockNotify.fetchLatestBlock(); if (currentBlock != -1) { - if (currentBlock != getBlockHeight()) { + if (currentBlock != blockNotify.getBlockHeight()) { Serial.println(F("Detected stuck block height... restarting block handler.")); - restartBlockNotify(); + blockNotify.restart(); } - setLastBlockUpdate(getUptime()); + blockNotify.setLastBlockUpdate(getUptime()); } } @@ -111,9 +114,10 @@ void monitorDataConnections() { } // Block notification monitoring - if (getBlockNotifyInit() && !isBlockNotifyConnected()) { + auto& blockNotify = BlockNotify::getInstance(); + if (blockNotify.isInitialized() && !blockNotify.isConnected()) { handleBlockNotifyDisconnection(); - } else if (blockNotifyLostConnection > 0 && isBlockNotifyConnected()) { + } else if (blockNotifyLostConnection > 0 && blockNotify.isConnected()) { blockNotifyLostConnection = 0; } @@ -125,7 +129,7 @@ void monitorDataConnections() { } // Check for missed blocks - if ((getLastBlockUpdate() - getUptime()) > 45 * 60) { + if ((blockNotify.getLastBlockUpdate() - getUptime()) > 45 * 60) { checkMissedBlocks(); } }