From 639775f23c254e0ac1f850d6b0e59b83181912e5 Mon Sep 17 00:00:00 2001 From: Dirk Moeller Date: Sun, 21 Apr 2024 12:50:39 +0000 Subject: [PATCH 01/21] add BM1366_set_chip_address (needed for unit test to work) --- components/bm1397/bm1366.c | 25 +++++++++++++++++++++++++ components/bm1397/include/bm1366.h | 1 + 2 files changed, 26 insertions(+) diff --git a/components/bm1397/bm1366.c b/components/bm1397/bm1366.c index 4833acf8b..cccda388e 100644 --- a/components/bm1397/bm1366.c +++ b/components/bm1397/bm1366.c @@ -456,51 +456,67 @@ static uint8_t _send_init(uint64_t frequency) } ESP_LOGI(TAG, "%i chip(s) detected on the chain", chip_counter); + //Reg_A8 unsigned char init4[11] = {0x55, 0xAA, 0x51, 0x09, 0x00, 0xA8, 0x00, 0x07, 0x00, 0x00, 0x03}; _send_simple(init4, 11); + //Misc Control unsigned char init5[11] = {0x55, 0xAA, 0x51, 0x09, 0x00, 0x18, 0xFF, 0x0F, 0xC1, 0x00, 0x00}; _send_simple(init5, 11); + //chain inactive unsigned char init6[7] = {0x55, 0xAA, 0x53, 0x05, 0x00, 0x00, 0x03}; _send_simple(init6, 7); + //set chip address unsigned char init7[7] = {0x55, 0xAA, 0x40, 0x05, 0x00, 0x00, 0x1C}; _send_simple(init7, 7); + //Core Register Control unsigned char init135[11] = {0x55, 0xAA, 0x51, 0x09, 0x00, 0x3C, 0x80, 0x00, 0x85, 0x40, 0x0C}; _send_simple(init135, 11); + //Core Register Control unsigned char init136[11] = {0x55, 0xAA, 0x51, 0x09, 0x00, 0x3C, 0x80, 0x00, 0x80, 0x20, 0x19}; _send_simple(init136, 11); + //set ticket mask unsigned char init137[11] = {0x55, 0xAA, 0x51, 0x09, 0x00, 0x14, 0x00, 0x00, 0x00, 0xFF, 0x08}; _send_simple(init137, 11); + //Analog Mux Control unsigned char init138[11] = {0x55, 0xAA, 0x51, 0x09, 0x00, 0x54, 0x00, 0x00, 0x00, 0x03, 0x1D}; _send_simple(init138, 11); + //Set the IO Driver Strength on chip 00 unsigned char init139[11] = {0x55, 0xAA, 0x51, 0x09, 0x00, 0x58, 0x02, 0x11, 0x11, 0x11, 0x06}; _send_simple(init139, 11); + //UART Relay for each chip unsigned char init171[11] = {0x55, 0xAA, 0x41, 0x09, 0x00, 0x2C, 0x00, 0x7C, 0x00, 0x03, 0x03}; _send_simple(init171, 11); + //FAST_UART_CONFIGURATION unsigned char init173[11] = {0x55, 0xAA, 0x51, 0x09, 0x00, 0x28, 0x11, 0x30, 0x02, 0x00, 0x03}; _send_simple(init173, 11); + //Reg_A8 for each chip unsigned char init174[11] = {0x55, 0xAA, 0x41, 0x09, 0x00, 0xA8, 0x00, 0x07, 0x01, 0xF0, 0x15}; _send_simple(init174, 11); + //Misc Control for each chip unsigned char init175[11] = {0x55, 0xAA, 0x41, 0x09, 0x00, 0x18, 0xF0, 0x00, 0xC1, 0x00, 0x0C}; _send_simple(init175, 11); + //Core Register Control for each chip unsigned char init176[11] = {0x55, 0xAA, 0x41, 0x09, 0x00, 0x3C, 0x80, 0x00, 0x85, 0x40, 0x04}; _send_simple(init176, 11); + //Core Register Control for each chip unsigned char init177[11] = {0x55, 0xAA, 0x41, 0x09, 0x00, 0x3C, 0x80, 0x00, 0x80, 0x20, 0x11}; _send_simple(init177, 11); + //Core Register Control for each chip unsigned char init178[11] = {0x55, 0xAA, 0x41, 0x09, 0x00, 0x3C, 0x80, 0x00, 0x82, 0xAA, 0x05}; _send_simple(init178, 11); @@ -558,6 +574,15 @@ uint8_t BM1366_init(uint64_t frequency) return _send_init(frequency); } +void BM1366_set_chip_address(uint8_t chipAddr) +{ + // set all chips to chain_inactive mode + _send_chain_inactive(); + + // set new chip address. First chip in chain_inactive mode will now be addressed by the new address + _set_chip_address(chipAddr); +} + // Baud formula = 25M/((denominator+1)*8) // The denominator is 5 bits found in the misc_control (bits 9-13) int BM1366_set_default_baud(void) diff --git a/components/bm1397/include/bm1366.h b/components/bm1397/include/bm1366.h index b9cfc4290..8bf5c045f 100644 --- a/components/bm1397/include/bm1366.h +++ b/components/bm1397/include/bm1366.h @@ -40,5 +40,6 @@ int BM1366_set_max_baud(void); int BM1366_set_default_baud(void); void BM1366_send_hash_frequency(float frequency); task_result * BM1366_proccess_work(void * GLOBAL_STATE); +void BM1366_set_chip_address(uint8_t chipAddr); #endif /* BM1366_H_ */ \ No newline at end of file From 65800a7bc01fd708f4ecc7d0e19affac04c49398 Mon Sep 17 00:00:00 2001 From: Dirk Moeller Date: Sun, 21 Apr 2024 12:58:17 +0000 Subject: [PATCH 02/21] add BM1366 unit test - Testing one single BM1366 chip against a known valid block. Include script for block validation. --- components/bm1397/test/CMakeLists.txt | 24 ++- .../bm1397/test/log/test_bm1366_output.md | 147 +++++++++++++ components/bm1397/test/test_bm1366.c | 194 ++++++++++++++++++ .../test/verifiers/validate_btc_block.py | 49 +++++ 4 files changed, 411 insertions(+), 3 deletions(-) create mode 100644 components/bm1397/test/log/test_bm1366_output.md create mode 100644 components/bm1397/test/test_bm1366.c create mode 100644 components/bm1397/test/verifiers/validate_btc_block.py diff --git a/components/bm1397/test/CMakeLists.txt b/components/bm1397/test/CMakeLists.txt index 32386eaf0..c0f550907 100644 --- a/components/bm1397/test/CMakeLists.txt +++ b/components/bm1397/test/CMakeLists.txt @@ -1,3 +1,21 @@ -idf_component_register(SRC_DIRS "." - INCLUDE_DIRS "." - REQUIRES cmock stratum bm1397) \ No newline at end of file +idf_component_register( + SRCS + "test_bm1366.c" + "../../../main/adc.c" + "../../../main/nvs_config.c" + "../../../main/EMC2101.c" + "../../../main/DS4432U.c" + INCLUDE_DIRS + "." + "../include" + "../../../main" + "../../../main/tasks" + + REQUIRES unity cmock stratum bm1397 nvs_flash esp_adc esp_event connect +) + +# Include the header files from "main" directory +target_include_directories(${COMPONENT_LIB} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../main") + +# Include the header files from "main/tasks" directory +target_include_directories(${COMPONENT_LIB} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../main/tasks") \ No newline at end of file diff --git a/components/bm1397/test/log/test_bm1366_output.md b/components/bm1397/test/log/test_bm1366_output.md new file mode 100644 index 000000000..5433edb08 --- /dev/null +++ b/components/bm1397/test/log/test_bm1366_output.md @@ -0,0 +1,147 @@ +export IDF_PATH=/opt/esp/idf +/opt/esp/python_env/idf5.3_py3.10_env/bin/python /opt/esp/idf/tools/idf_monitor.py -p /dev/ttyACM0 -b 115200 --toolchain-prefix xtensa-esp32s3-elf- --target esp32s3 /workspaces/build/esp-miner.elf +root@31cc35ad06b6:/workspaces# export IDF_PATH=/opt/esp/idf +root@31cc35ad06b6:/workspaces# /opt/esp/python_env/idf5.3_py3.10_env/bin/python /opt/esp/idf/tools/idf_monitor.py -p /dev/ttyACM0 -b 115200 --toolchain-prefix xtensa-esp32s3-elf- --target esp32s3 /workspaces/build/esp-miner.elf +--- esp-idf-monitor 1.4.0 on /dev/ttyACM0 115200 --- +--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H --- +I (115) esp_image: segment 1: paddr=00023ec4 vaddr=3fc93cESP-ROM:esp32s3-20210327 +Build:Mar 27 2021 +rst:0x15 (USB_UART_CHIP_RESET),boot:0x28 (SPI_FAST_FLASH_BOOT) +Saved PC:0x40378db6 +0x40378db6: esp_random at /opt/esp/idf/components/esp_hw_support/hw_random.c:84 (discriminator 1) + +SPIWP:0xee +mode:DIO, clock div:1 +load:0x3fce2810,len:0x178c +load:0x403c8700,len:0x4 +load:0x403c8704,len:0xcb8 +load:0x403cb700,len:0x2d9c +entry 0x403c8914 +I (26) boot: ESP-IDF v5.3-dev-3225-g5a40bb8746 2nd stage bootloader +I (27) boot: compile time Apr 18 2024 07:48:00 +I (27) boot: Multicore bootloader +I (31) boot: chip revision: v0.2 +I (35) boot.esp32s3: Boot SPI Speed : 80MHz +I (40) boot.esp32s3: SPI Mode : DIO +I (45) boot.esp32s3: SPI Flash Size : 2MB +I (49) boot: Enabling RNG early entropy source... +I (55) boot: Partition Table: +I (58) boot: ## Label Usage Type ST Offset Length +I (66) boot: 0 nvs WiFi data 01 02 00009000 00006000 +I (73) boot: 1 phy_init RF data 01 01 0000f000 00001000 +I (81) boot: 2 factory factory app 00 00 00010000 00100000 +I (88) boot: End of partition table +I (92) esp_image: segment 0: paddr=00010020 vaddr=3c040020 size=13e9ch ( 81564) map +I (115) esp_image: segment 1: paddr=00023ec4 vaddr=3fc93c00 size=03228h ( 12840) load +I (119) esp_image: segment 2: paddr=000270f4 vaddr=40374000 size=08f24h ( 36644) load +I (129) esp_image: segment 3: paddr=00030020 vaddr=42000020 size=32d80h (208256) map +I (167) esp_image: segment 4: paddr=00062da8 vaddr=4037cf24 size=06c94h ( 27796) load +I (180) boot: Loaded app from partition at offset 0x10000 +I (180) boot: Disabling RNG early entropy source... +I (183) cpu_start: Multicore app +I (192) cpu_start: Pro cpu start user code +I (192) cpu_start: cpu freq: 160000000 Hz +I (192) app_init: Application information: +I (195) app_init: Project name: unit_test_stratum +I (201) app_init: App version: 07e7d41 +I (206) app_init: Compile time: Apr 21 2024 12:19:07 +I (212) app_init: ELF file SHA256: 0c91dab32... +I (217) app_init: ESP-IDF: v5.3-dev-3225-g5a40bb8746 +I (223) efuse_init: Min chip rev: v0.0 +I (228) efuse_init: Max chip rev: v0.99 +I (233) efuse_init: Chip rev: v0.2 +I (238) heap_init: Initializing. RAM available for dynamic allocation: +I (245) heap_init: At 3FC98C00 len 00050B10 (322 KiB): RAM +I (251) heap_init: At 3FCE9710 len 00005724 (21 KiB): RAM +I (257) heap_init: At 3FCF0000 len 00008000 (32 KiB): DRAM +I (263) heap_init: At 600FE100 len 00001EE8 (7 KiB): RTCRAM +I (271) spi_flash: detected chip: gd +I (274) spi_flash: flash io: dio +I (310) sleep: Configure to isolate all GPIO pins in sleep state +I (317) sleep: Enable automatic switching of GPIO sleep configuration +I (324) main_task: Started on CPU0 +I (334) main_task: Calling app_main() + +#### Running all the registered tests ##### + +Running Testing single BM1366 chip against a known valid block... +I (384) test_bm1366: ASIC: BM1366 +I (384) test_bm1366: I2C initialized successfully +I (384) DS4432U.c: Set ASIC voltage = 1.250V [0xB9] +I (384) DS4432U.c: Writing 0xB9 +I (394) serial: Initializing serial +I (394) bm1366Module: Initializing BM1366 +I (1594) bm1366Module: 1 chip(s) detected on the chain +final refdiv: 2, fbdiv: 220, postdiv1: 5, postdiv2: 1, min diff value: 0.000000 +I (1624) bm1366Module: Setting Frequency to 550.00MHz (0.01) +I (1624) bm1366Module: Setting max baud of 1000000 +I (1634) serial: Changing UART baud to 1000000 +I (1634) test_bm1366: BM1366 is ready and waiting for work +I (1644) test_bm1366: Preparing job +I (1644) bm1366Module: Setting job ASIC mask to 511 +I (1654) test_bm1366: Changing chip address and sending job; new chip address: 0xc0 +I (1664) test_bm1366: Waiting for result ... (might take a while due to 60s timeout) +I (2114) test_bm1366: Result[1]: Nonce 3818226259 Nonce difficulty 8452.86377870396427169907838106155396. rolled-version 0x24148000 +I (3974) test_bm1366: Result[2]: Nonce 504135883 Nonce difficulty 816.88959549147682537295622751116753. rolled-version 0x349cc000 +I (5704) test_bm1366: Result[3]: Nonce 3818226259 Nonce difficulty 8452.86377870396427169907838106155396. rolled-version 0x24148000 +I (7554) test_bm1366: Result[4]: Nonce 504135883 Nonce difficulty 816.88959549147682537295622751116753. rolled-version 0x349cc000 +I (9294) test_bm1366: Result[5]: Nonce 3818226259 Nonce difficulty 8452.86377870396427169907838106155396. rolled-version 0x24148000 +I (11144) test_bm1366: Result[6]: Nonce 504135883 Nonce difficulty 816.88959549147682537295622751116753. rolled-version 0x349cc000 +I (12874) test_bm1366: Result[7]: Nonce 3818226259 Nonce difficulty 8452.86377870396427169907838106155396. rolled-version 0x24148000 +I (14724) test_bm1366: Result[8]: Nonce 504135883 Nonce difficulty 816.88959549147682537295622751116753. rolled-version 0x349cc000 +I (16464) test_bm1366: Result[9]: Nonce 3818226259 Nonce difficulty 8452.86377870396427169907838106155396. rolled-version 0x24148000 +I (18314) test_bm1366: Result[10]: Nonce 504135883 Nonce difficulty 816.88959549147682537295622751116753. rolled-version 0x349cc000 +I (20044) test_bm1366: Changing chip address and sending job; new chip address: 0xc2 +I (20044) test_bm1366: Waiting for result ... (might take a while due to 60s timeout) +I (21064) test_bm1366: Result[1]: Nonce 3118696143 Nonce difficulty 1007.71313585765790321602253243327141. rolled-version 0x2915a000 +I (21234) test_bm1366: Result[2]: Nonce 3529540887 Nonce difficulty 125538251293054.07812500000000000000000000000000. rolled-version 0x2a966000 +I (21234) test_bm1366: Expected nonce and version match. Solution found! +/workspaces/components/bm1397/test/test_bm1366.c:23:Testing single BM1366 chip against a known valid block:PASS +Running Check coinbase tx construction... +/workspaces/components/stratum/test/test_mining.c:7:Check coinbase tx construction:PASS +Running Validate merkle root calculation... +/workspaces/components/stratum/test/test_mining.c:19:Validate merkle root calculation:PASS +Running Validate another merkle root calculation... +/workspaces/components/stratum/test/test_mining.c:43:Validate another merkle root calculation:PASS +Running Validate bm job construction... +/workspaces/components/stratum/test/test_mining.c:75:Validate bm job construction:FAIL: Element 0 Expected 77 Was 214. Function [mining] +Running Validate version mask incrementing... +/workspaces/components/stratum/test/test_mining.c:78:Validate version mask incrementing:PASS +Running Test extranonce 2 generation... +/workspaces/components/stratum/test/test_mining.c:118:Test extranonce 2 generation:PASS +Running Test nonce diff checking... +/workspaces/components/stratum/test/test_mining.c:153:Test nonce diff checking:FAIL: Expected 18 Was 0. Function [mining test_nonce] +Running Test nonce diff checking 2... +/workspaces/components/stratum/test/test_mining.c:189:Test nonce diff checking 2:FAIL: Expected 683 Was 0. Function [mining test_nonce] +Running Parse stratum method... +/workspaces/components/stratum/test/test_stratum_json.c:4:Parse stratum method:PASS +Running Parse stratum mining.notify abandon work... +/workspaces/components/stratum/test/test_stratum_json.c:21:Parse stratum mining.notify abandon work:PASS +Running Parse stratum set_difficulty params... +/workspaces/components/stratum/test/test_stratum_json.c:62:Parse stratum set_difficulty params:PASS +Running Parse stratum notify params... +/workspaces/components/stratum/test/test_stratum_json.c:71:Parse stratum notify params:PASS +Running Parse stratum mining.set_version_mask params... +/workspaces/components/stratum/test/test_stratum_json.c:108:Parse stratum mining.set_version_mask params:PASS +Running Parse stratum result success... +/workspaces/components/stratum/test/test_stratum_json.c:118:Parse stratum result success:PASS +Running Parse stratum result error... +/workspaces/components/stratum/test/test_stratum_json.c:128:Parse stratum result error:PASS +Running Test double sha... +/workspaces/components/stratum/test/test_utils.c:5:Test double sha:PASS +Running Test hex2bin... +/workspaces/components/stratum/test/test_utils.c:12:Test hex2bin:PASS +Running Test bin2hex... +/workspaces/components/stratum/test/test_utils.c:25:Test bin2hex:PASS +Running Test hex2char... +/workspaces/components/stratum/test/test_utils.c:33:Test hex2char:PASS + +----------------------- +20 Tests 3 Failures 0 Ignored +FAIL + +#### Starting interactive test menu ##### + + + +Press ENTER to see the list of tests. diff --git a/components/bm1397/test/test_bm1366.c b/components/bm1397/test/test_bm1366.c new file mode 100644 index 000000000..9e807e858 --- /dev/null +++ b/components/bm1397/test/test_bm1366.c @@ -0,0 +1,194 @@ +#include "unity.h" +#include "serial.h" +#include "bm1366.h" +#include "common.h" +#include "DS4432U.h" +#include "EMC2101.h" +#include "INA260.h" +#include "adc.h" +#include "driver/i2c.h" +#include "esp_log.h" +#include "global_state.h" +#include "nvs_config.h" +#include "nvs_flash.h" +#include "oled.h" +#include "utils.h" + +#include + +static GlobalState GLOBAL_STATE = {.extranonce_str = NULL, .extranonce_2_len = 0, .abandon_work = 0, .version_mask = 0}; + +static const char * TAG = "test_bm1366"; + +TEST_CASE("Testing one single BM1366 chip against a known valid block", "[bm1366]") +{ + ESP_ERROR_CHECK(nvs_flash_init()); + + GLOBAL_STATE.POWER_MANAGEMENT_MODULE.frequency_value = nvs_config_get_u16(NVS_CONFIG_ASIC_FREQ, 485); + TEST_ASSERT_LESS_OR_EQUAL_UINT(575, GLOBAL_STATE.POWER_MANAGEMENT_MODULE.frequency_value); + + GLOBAL_STATE.asic_model = nvs_config_get_string(NVS_CONFIG_ASIC_MODEL, ""); + TEST_ASSERT_EQUAL_STRING("BM1366", GLOBAL_STATE.asic_model); + + if (strcmp(GLOBAL_STATE.asic_model, "BM1366") == 0) { + ESP_LOGI(TAG, "ASIC: BM1366"); + AsicFunctions ASIC_functions = {.init_fn = BM1366_init, + .receive_result_fn = BM1366_proccess_work, + .set_max_baud_fn = BM1366_set_max_baud, + .set_difficulty_mask_fn = BM1366_set_job_difficulty_mask, + .send_work_fn = BM1366_send_work}; + GLOBAL_STATE.ASIC_functions = ASIC_functions; + + } else { + ESP_LOGI(TAG, "Invalid ASIC model"); + AsicFunctions ASIC_functions = {.init_fn = NULL, + .receive_result_fn = NULL, + .set_max_baud_fn = NULL, + .set_difficulty_mask_fn = NULL, + .send_work_fn = NULL}; + GLOBAL_STATE.ASIC_functions = ASIC_functions; + } + + GLOBAL_STATE.ASIC_TASK_MODULE.active_jobs = malloc(sizeof(bm_job *) * 128); + GLOBAL_STATE.valid_jobs = malloc(sizeof(uint8_t) * 128); + for (int i = 0; i < 128; i++) { + + GLOBAL_STATE.ASIC_TASK_MODULE.active_jobs[i] = NULL; + GLOBAL_STATE.valid_jobs[i] = 0; + } + + // Init I2C + ESP_ERROR_CHECK(i2c_master_init()); + ESP_LOGI(TAG, "I2C initialized successfully"); + + // init ADC and set DS4432U voltage + ADC_init(); + DS4432U_set_vcore(nvs_config_get_u16(NVS_CONFIG_ASIC_VOLTAGE, 1200) / 1000.0); + + // init EMC2101 and set FAN speed to 100% + EMC2101_init(nvs_config_get_u16(NVS_CONFIG_INVERT_FAN_POLARITY, 1)); + EMC2101_set_fan_speed(1); + + // turn ASIC on + gpio_set_direction(GPIO_NUM_10, GPIO_MODE_OUTPUT); + gpio_set_level(GPIO_NUM_10, 0); + + // init serial communication + SERIAL_init(); + + uint8_t chips_detected = (*GLOBAL_STATE.ASIC_functions.init_fn)(GLOBAL_STATE.POWER_MANAGEMENT_MODULE.frequency_value); + TEST_ASSERT_EQUAL_INT8(1, chips_detected); // to be adapted to the number of chips expected + + // set max baud rate + SERIAL_set_baud((*GLOBAL_STATE.ASIC_functions.set_max_baud_fn)()); + + ESP_LOGI(TAG, "%s is ready and waiting for work", GLOBAL_STATE.asic_model); + + /* Block #839900 + {"id":null,"method":"mining.notify","params":[ + "185abf4", //job_id + "10439ba3ef4739860fb382d2abd355f7ee767c2400015d7e0000000000000000", //prev_block_hash + "02000000010000000000000000000000000000000000000000000000000000000000000000ffffffff1703dcd00c5075626c69632d506f6f6c", //coinbase_1 + "ffffffff025ef88d2700000000160014979f36b9a92622b82767820f6477bdefc03e86b70000000000000000266a24aa21a9ed4b7e3a6c3bf8bff6e793b507392ae3cb0deab4c8908ce351e61d0af0ac06bdc000000000", //coinbase_2 + [ + "7e3f8209b0d3e7fcfaf4c89162636bc1756d2bc3bfcdc7a7135136ff6d7b0069", + "e66c3e07dee92d95bb4895580fb3584f2fe1d29033818846286e23cddf9bf572", + "5a9ff7e4b64934437af73e3fa4e5a783d9b1421de19a605b8e30edfce5d055a5", + "d3d38299563f8a6cac7821096c6e9f8fbbe77bd063adb0687035f5cde2ff4dd0", + "72dca2b4288e4288d1c9b79df8b88b0a24e3f85e901e99eeb62014288651ef26", + "b417f18e7774cb36e5009f239fe08c1407dde49a7b19cf4230b67de9a348b502", + "01261cd686cde5b97cf989953b0a0e1630c016f187a6f6e7fc44b40c950d3571", + "6076764edef31739c715acfe5d2a480624779998987d60520033b731da129f37", + "a953f2b682496e2777938d01f7a6626435406236d8caa64fb8a7f2a9bd05e6ff", + "479e0549bd963a3d7f6747bdd3f615fced29a003d959d4c740c29a49943d16cf", + "a1714ab576e5228e10ee4b6aa032412e9c20015b52a4516842358fb28cef3c7e", + "fcb3c52ae1f391246b6250c178040d6b7fa9725391a65315e6e9dc0c1e32e336" + ], + "20000000", //version + "17034219", //target + "66221ad7", //ntime + false] //clear_jobs + } + */ + + ESP_LOGI(TAG, "Preparing job"); + mining_notify notify_message; + notify_message.job_id = 839900; //Block #839900 - see above https://blockchain.info/rawblock/000000000000000000023dfafae2b6e6b5ecf9d1365fafa075dec49625721f37 or https://bitcoinexplorer.org/block-height/839900#JSON + notify_message.prev_block_hash = "10439ba3ef4739860fb382d2abd355f7ee767c2400015d7e0000000000000000"; + notify_message.version = 0x20000000; // from mining.notify to test version rolling + notify_message.target = 0x17034219; + notify_message.ntime = 0x66221BDF; // actual time of resolved block, see blockchain.info/... + notify_message.difficulty = 1000; // can be as high as 652198270 + const uint32_t expected_nonce = 3529540887; + const uint32_t expected_version = 0x2a966000; + + // actual merkle_root of block #839900, see see blockchain.info/... or https://bitcoinexplorer.org/block-height/839900#JSON + char * merkle_root = "088083f58ddef995494fec492880da49e3463cc73dee1306dbdf6cf3af77454c"; + + // construct job + bm_job job = construct_bm_job(¬ify_message, merkle_root, 0); + + /* debug code, should be removed once test is functional */ + // ESP_LOGI(TAG, "job.prev_block_hash:"); + // ESP_LOG_BUFFER_HEX(TAG, job.prev_block_hash, 32); + // ESP_LOGI(TAG, "job.prev_block_hash_be:"); + // ESP_LOG_BUFFER_HEX(TAG, job.prev_block_hash_be, 32); + // ESP_LOGI(TAG, "job.merkle_root:"); + // ESP_LOG_BUFFER_HEX(TAG, job.merkle_root, 32); + // ESP_LOGI(TAG, "job.merkle_root_be:"); + // ESP_LOG_BUFFER_HEX(TAG, job.merkle_root_be, 32); + + // set difficulty mask + (*GLOBAL_STATE.ASIC_functions.set_difficulty_mask_fn)(notify_message.difficulty); + + task_result * asic_result = NULL; + + // Why do we need to change the chip address? see https://youtu.be/6o92HhvOc1I?t=5710 for a more detailed explanation. + // It seems that the chip (each chip address) has a different nonce space and + // in order to cover the whole nonce space, we need to have 128 chips (chip address 0-127). + // So we need to change the chip address to selecct the correct nonce space. + // The solution for block #839900 (the block we are using in this test) should be in nonce space of chip address 0xc2. + // In order to show and proof the different nonce scapes per chip address, we start at 96 (96 * 2 = 192 = 0xc0). + // It is expected to not find a solution in nonce space of chip address 0xc0. + // This unit test is designed to test one single BM1366 chip. + for (uint8_t i = 96; i < 128; i++) { + + uint8_t chip_address = i * 2; + + ESP_LOGI(TAG, "Changing chip address and sending job; new chip address: 0x%02x", chip_address); + BM1366_set_chip_address(chip_address); + (*GLOBAL_STATE.ASIC_functions.send_work_fn)(&GLOBAL_STATE, &job); + + ESP_LOGI(TAG, "Waiting for result ... (might take a while due to 60s timeout)"); + asic_result = (*GLOBAL_STATE.ASIC_functions.receive_result_fn)(&GLOBAL_STATE); + + int counter = 1; + while (asic_result != NULL && counter <= 10) { + + double nonce_diff = test_nonce_value(&job, asic_result->nonce, asic_result->rolled_version); + ESP_LOGI(TAG, "Result[%d]: Nonce %lu Nonce difficulty %.32f. rolled-version 0x%08lx", counter, asic_result->nonce, nonce_diff, asic_result->rolled_version); + + if (asic_result->nonce == expected_nonce && asic_result->rolled_version == expected_version) { + ESP_LOGI(TAG, "Expected nonce and version match. Solution found!"); + break; + } + + asic_result = (*GLOBAL_STATE.ASIC_functions.receive_result_fn)(&GLOBAL_STATE); // wait for next result + counter++; + } + if (asic_result != NULL && asic_result->nonce == expected_nonce) { + break; + } + } + + free(GLOBAL_STATE.ASIC_TASK_MODULE.active_jobs); + free(GLOBAL_STATE.valid_jobs); + + // turn ASIC off + gpio_set_direction(GPIO_NUM_10, GPIO_MODE_OUTPUT); + gpio_set_level(GPIO_NUM_10, 1); + + TEST_ASSERT_NOT_NULL(asic_result); + TEST_ASSERT_EQUAL_UINT32(expected_nonce, asic_result->nonce); +} + diff --git a/components/bm1397/test/verifiers/validate_btc_block.py b/components/bm1397/test/verifiers/validate_btc_block.py new file mode 100644 index 000000000..656e0acd5 --- /dev/null +++ b/components/bm1397/test/verifiers/validate_btc_block.py @@ -0,0 +1,49 @@ +import hashlib +from binascii import unhexlify, hexlify + +""" +Block #839900, data from https://blockchain.info/rawblock/000000000000000000023dfafae2b6e6b5ecf9d1365fafa075dec49625721f37 +This script is based on https://github.com/Tennyx/validate-btc-block +""" +btc_version = 714498048 +hex_prev_hash = "000000000000000000015d7eee767c24abd355f70fb382d2ef47398610439ba3" +hex_merkle_hash = "088083f58ddef995494fec492880da49e3463cc73dee1306dbdf6cf3af77454c" +epoch_time = 1713511391 +bits = 386089497 +nonce = 3529540887 + +def endian_big_to_little(hex): + padded_hex = '' + if len(hex) != 8: + padding_len = 8 - len(hex) + for num in range(padding_len): + padded_hex += '0' + padded_hex += str(hex) + else: + padded_hex = hex + ba = bytearray.fromhex(padded_hex) + ba.reverse() + le_hex = ''.join(format(x, '02x') for x in ba) + return le_hex + +hex_btc_version = endian_big_to_little(hex(btc_version)[2:]) +hex_prev_hash = endian_big_to_little(hex_prev_hash) +hex_merkle_hash = endian_big_to_little(hex_merkle_hash) +hex_time = endian_big_to_little(hex(int(epoch_time))[2:]) +hex_bits = endian_big_to_little(hex(bits)[2:]) +hex_nonce = endian_big_to_little(hex(nonce)[2:]) + +header_hex = ( + hex_btc_version + + hex_prev_hash + + hex_merkle_hash + + hex_time + + hex_bits + + hex_nonce +) + +header_bin = unhexlify(header_hex) +print("header:", hexlify(header_bin).decode("utf-8")) +hash = hashlib.sha256(hashlib.sha256(header_bin).digest()).digest() +print("hash:", hexlify(hash[::-1]).decode("utf-8")) + From b922e3ebfcc153de67221d072c7cd681c58ec4b0 Mon Sep 17 00:00:00 2001 From: Dirk Moeller Date: Sun, 21 Apr 2024 13:01:28 +0000 Subject: [PATCH 03/21] fix construct_bm_job - new_job.merkle_root instead of new_job.merkle_root_be needs to be reversed. confirmed by validation script as well as unit test running on real hardware (bitaxe 205 ultra, bm1366) --- components/stratum/mining.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/stratum/mining.c b/components/stratum/mining.c index 0a0b7bd61..2946de767 100644 --- a/components/stratum/mining.c +++ b/components/stratum/mining.c @@ -63,10 +63,10 @@ bm_job construct_bm_job(mining_notify *params, const char *merkle_root, const ui new_job.pool_diff = params->difficulty; hex2bin(merkle_root, new_job.merkle_root, 32); + reverse_bytes(new_job.merkle_root, 32); // hex2bin(merkle_root, new_job.merkle_root_be, 32); swap_endian_words(merkle_root, new_job.merkle_root_be); - reverse_bytes(new_job.merkle_root_be, 32); swap_endian_words(params->prev_block_hash, new_job.prev_block_hash); From 52954435e35f33e3a497240ba686bc8048c73919 Mon Sep 17 00:00:00 2001 From: Dirk Moeller Date: Sun, 21 Apr 2024 18:12:32 +0000 Subject: [PATCH 04/21] Revert "fix construct_bm_job - new_job.merkle_root instead of new_job.merkle_root_be needs to be reversed. confirmed by validation script as well as unit test running on real hardware (bitaxe 205 ultra, bm1366)" This reverts commit b922e3ebfcc153de67221d072c7cd681c58ec4b0. --- components/stratum/mining.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/stratum/mining.c b/components/stratum/mining.c index 2946de767..0a0b7bd61 100644 --- a/components/stratum/mining.c +++ b/components/stratum/mining.c @@ -63,10 +63,10 @@ bm_job construct_bm_job(mining_notify *params, const char *merkle_root, const ui new_job.pool_diff = params->difficulty; hex2bin(merkle_root, new_job.merkle_root, 32); - reverse_bytes(new_job.merkle_root, 32); // hex2bin(merkle_root, new_job.merkle_root_be, 32); swap_endian_words(merkle_root, new_job.merkle_root_be); + reverse_bytes(new_job.merkle_root_be, 32); swap_endian_words(params->prev_block_hash, new_job.prev_block_hash); From dd7e0a1cd63b3860c33032c0b1f9afb38c1fa3bc Mon Sep 17 00:00:00 2001 From: Dirk Moeller Date: Sun, 21 Apr 2024 19:28:03 +0000 Subject: [PATCH 05/21] the merkle_root copied from blockchain.info needs to be in reversed order --- components/bm1397/test/test_bm1366.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/components/bm1397/test/test_bm1366.c b/components/bm1397/test/test_bm1366.c index 9e807e858..25bd86d93 100644 --- a/components/bm1397/test/test_bm1366.c +++ b/components/bm1397/test/test_bm1366.c @@ -125,6 +125,12 @@ TEST_CASE("Testing one single BM1366 chip against a known valid block", "[bm1366 // actual merkle_root of block #839900, see see blockchain.info/... or https://bitcoinexplorer.org/block-height/839900#JSON char * merkle_root = "088083f58ddef995494fec492880da49e3463cc73dee1306dbdf6cf3af77454c"; + // The merkle_root copied from blockchain.info needs to be in reversed order. Maybe there is a better way to do this? + uint8_t merkle_root_rev[32]; + hex2bin(merkle_root, merkle_root_rev, 32); + reverse_bytes(merkle_root_rev, 32); + bin2hex(merkle_root_rev, 32, merkle_root, 64); + // construct job bm_job job = construct_bm_job(¬ify_message, merkle_root, 0); @@ -148,7 +154,7 @@ TEST_CASE("Testing one single BM1366 chip against a known valid block", "[bm1366 // in order to cover the whole nonce space, we need to have 128 chips (chip address 0-127). // So we need to change the chip address to selecct the correct nonce space. // The solution for block #839900 (the block we are using in this test) should be in nonce space of chip address 0xc2. - // In order to show and proof the different nonce scapes per chip address, we start at 96 (96 * 2 = 192 = 0xc0). + // In order to show and proof the different nonce spaces per chip address, we start at 96 (96 * 2 = 192 = 0xc0). // It is expected to not find a solution in nonce space of chip address 0xc0. // This unit test is designed to test one single BM1366 chip. for (uint8_t i = 96; i < 128; i++) { From e67c300fc4b3ff4d1ac63c201b350ae8ec8fca8a Mon Sep 17 00:00:00 2001 From: Dirk Moeller Date: Fri, 26 Apr 2024 21:42:23 +0000 Subject: [PATCH 06/21] add rollover detection --- components/bm1397/test/test_bm1366.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/components/bm1397/test/test_bm1366.c b/components/bm1397/test/test_bm1366.c index 25bd86d93..9943be1a6 100644 --- a/components/bm1397/test/test_bm1366.c +++ b/components/bm1397/test/test_bm1366.c @@ -167,12 +167,23 @@ TEST_CASE("Testing one single BM1366 chip against a known valid block", "[bm1366 ESP_LOGI(TAG, "Waiting for result ... (might take a while due to 60s timeout)"); asic_result = (*GLOBAL_STATE.ASIC_functions.receive_result_fn)(&GLOBAL_STATE); + if (asic_result == NULL) { continue; } + + uint32_t version = asic_result->rolled_version; + uint32_t nonce = 0; int counter = 1; - while (asic_result != NULL && counter <= 10) { + while (asic_result != NULL && counter <= 100) { + + if (asic_result->rolled_version < version || (asic_result->rolled_version == version && asic_result->nonce == nonce)) { + ESP_LOGI(TAG, "Rollover detected - Nonce %lu, Version 0x%08lx", asic_result->nonce, asic_result->rolled_version); + break; + } + version = asic_result->rolled_version; + nonce = asic_result->nonce; double nonce_diff = test_nonce_value(&job, asic_result->nonce, asic_result->rolled_version); - ESP_LOGI(TAG, "Result[%d]: Nonce %lu Nonce difficulty %.32f. rolled-version 0x%08lx", counter, asic_result->nonce, nonce_diff, asic_result->rolled_version); + ESP_LOGI(TAG, "Result[%d]: Nonce %lu (0x%08lx) Nonce difficulty %.32f. rolled-version 0x%08lx", counter, asic_result->nonce, asic_result->nonce, nonce_diff, asic_result->rolled_version); if (asic_result->nonce == expected_nonce && asic_result->rolled_version == expected_version) { ESP_LOGI(TAG, "Expected nonce and version match. Solution found!"); From 802e0c84ad6cfcd30e364410dccaab64ae6113d3 Mon Sep 17 00:00:00 2001 From: Dirk Moeller Date: Sat, 27 Apr 2024 10:46:47 +0000 Subject: [PATCH 07/21] update _set_chip_address --- components/bm1397/bm1366.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/bm1397/bm1366.c b/components/bm1397/bm1366.c index cccda388e..8f9fb7d30 100644 --- a/components/bm1397/bm1366.c +++ b/components/bm1397/bm1366.c @@ -118,12 +118,12 @@ static void _send_chain_inactive(void) _send_BM1366((TYPE_CMD | GROUP_ALL | CMD_INACTIVE), read_address, 2, false); } -static void _set_chip_address(uint8_t chipAddr) +static void _set_chip_address(uint8_t new_address) { - unsigned char read_address[2] = {chipAddr, 0x00}; + unsigned char send_address[2] = {new_address, 0x00}; // send serial data - _send_BM1366((TYPE_CMD | GROUP_SINGLE | CMD_SETADDRESS), read_address, 2, false); + _send_BM1366((TYPE_CMD | GROUP_SINGLE | CMD_SETADDRESS), send_address, 2, false); } void BM1366_send_hash_frequency(float target_freq) From 841bff4bae9489dc17de836acefe369368248232 Mon Sep 17 00:00:00 2001 From: Dirk Moeller Date: Sat, 27 Apr 2024 10:47:23 +0000 Subject: [PATCH 08/21] update _send_init - static chip_counter --- components/bm1397/bm1366.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/bm1397/bm1366.c b/components/bm1397/bm1366.c index 8f9fb7d30..f98809c47 100644 --- a/components/bm1397/bm1366.c +++ b/components/bm1397/bm1366.c @@ -59,6 +59,7 @@ static const char * TAG = "bm1366Module"; static uint8_t asic_response_buffer[CHUNK_SIZE]; static task_result result; +static int chip_counter = 0; // updated in _send_init /// @brief /// @param ftdi @@ -446,7 +447,7 @@ static uint8_t _send_init(uint64_t frequency) unsigned char init3[7] = {0x55, 0xAA, 0x52, 0x05, 0x00, 0x00, 0x0A}; _send_simple(init3, 7); - int chip_counter = 0; + chip_counter = 0; while (true) { if(SERIAL_rx(asic_response_buffer, 11, 1000) > 0) { chip_counter++; From 1aba19b291e9f24d443e66f9bd36056615b7b8e9 Mon Sep 17 00:00:00 2001 From: Dirk Moeller Date: Sat, 27 Apr 2024 10:48:06 +0000 Subject: [PATCH 09/21] update _send_init - new address interval, utilize existing code and update documentation --- components/bm1397/bm1366.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/components/bm1397/bm1366.c b/components/bm1397/bm1366.c index f98809c47..10fdca9c7 100644 --- a/components/bm1397/bm1366.c +++ b/components/bm1397/bm1366.c @@ -466,12 +466,12 @@ static uint8_t _send_init(uint64_t frequency) _send_simple(init5, 11); //chain inactive - unsigned char init6[7] = {0x55, 0xAA, 0x53, 0x05, 0x00, 0x00, 0x03}; - _send_simple(init6, 7); + _send_chain_inactive(); //set chip address - unsigned char init7[7] = {0x55, 0xAA, 0x40, 0x05, 0x00, 0x00, 0x1C}; - _send_simple(init7, 7); + for (int i = 0; i < chip_counter; i++) { + _set_chip_address(i * (0x100 / chip_counter)); + } //Core Register Control unsigned char init135[11] = {0x55, 0xAA, 0x51, 0x09, 0x00, 0x3C, 0x80, 0x00, 0x85, 0x40, 0x0C}; @@ -489,7 +489,7 @@ static uint8_t _send_init(uint64_t frequency) unsigned char init138[11] = {0x55, 0xAA, 0x51, 0x09, 0x00, 0x54, 0x00, 0x00, 0x00, 0x03, 0x1D}; _send_simple(init138, 11); - //Set the IO Driver Strength on chip 00 + //Set the IO Driver Strength unsigned char init139[11] = {0x55, 0xAA, 0x51, 0x09, 0x00, 0x58, 0x02, 0x11, 0x11, 0x11, 0x06}; _send_simple(init139, 11); From 186f9795bc400ce87ca20143ae6bffb53e48fcb8 Mon Sep 17 00:00:00 2001 From: Dirk Moeller Date: Sat, 27 Apr 2024 10:48:54 +0000 Subject: [PATCH 10/21] add BM1366_set_nonce_scope and renaming of BM1366_set_chip_address --- components/bm1397/bm1366.c | 28 +++++++++++++++++++++++++--- components/bm1397/include/bm1366.h | 3 ++- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/components/bm1397/bm1366.c b/components/bm1397/bm1366.c index 10fdca9c7..855760885 100644 --- a/components/bm1397/bm1366.c +++ b/components/bm1397/bm1366.c @@ -575,13 +575,35 @@ uint8_t BM1366_init(uint64_t frequency) return _send_init(frequency); } -void BM1366_set_chip_address(uint8_t chipAddr) +void BM1366_set_single_chip_address(uint8_t new_address) { // set all chips to chain_inactive mode _send_chain_inactive(); - // set new chip address. First chip in chain_inactive mode will now be addressed by the new address - _set_chip_address(chipAddr); + // set new chip address to first chip in chain_inactive mode. + _set_chip_address(new_address); +} + +void BM1366_set_nonce_scope(uint32_t chipmask) +{ + // 55 AA 51 09 00 10 00 00 11 5A 04 //s19kPro (77 chips) 0x115a + //unsigned char command[9] = {0x00, 0x10, 0b00000000, 0b00000000, 0b00010001, 0b01011010}; + // 55 AA 51 09 00 10 00 00 14 46 04 //s19xp_luxos (110 chips) 0x1446 + //unsigned char command[9] = {0x00, 0x10, 0b00000000, 0b00000000, 0b00010100, 0b01000110}; + // 55 AA 51 09 00 10 00 00 15 1C 02 //s19xp-stock / BitaxeUltra 0x151c + //unsigned char command[9] = {0x00, 0x10, 0b00000000, 0b00000000, 0b00010101, 0b00011100}; + + // Default mask for 128 chips (address interval 0x02) on chain + unsigned char command[9] = {0x00, 0x10, 0x00, 0x00, 0x15, 0x1C}; + + // convert into char array + for (int i = 0; i < 4; i++) { + char value = (chipmask >> (8 * i)) & 0xFF; + command[5 - i] = value; + } + + ESP_LOGI(TAG, "Setting Nonce scope to %lu (0x%08lx)", chipmask, chipmask); + _send_BM1366((TYPE_CMD | GROUP_ALL | CMD_WRITE), command, 6, true); } // Baud formula = 25M/((denominator+1)*8) diff --git a/components/bm1397/include/bm1366.h b/components/bm1397/include/bm1366.h index 8bf5c045f..b8c87690b 100644 --- a/components/bm1397/include/bm1366.h +++ b/components/bm1397/include/bm1366.h @@ -40,6 +40,7 @@ int BM1366_set_max_baud(void); int BM1366_set_default_baud(void); void BM1366_send_hash_frequency(float frequency); task_result * BM1366_proccess_work(void * GLOBAL_STATE); -void BM1366_set_chip_address(uint8_t chipAddr); +void BM1366_set_single_chip_address(uint8_t chipAddr); +void BM1366_set_nonce_scope(uint32_t chipmask); #endif /* BM1366_H_ */ \ No newline at end of file From d9f26b14f3e21c211863d641c5679307e04a7241 Mon Sep 17 00:00:00 2001 From: Dirk Moeller Date: Sat, 27 Apr 2024 10:49:27 +0000 Subject: [PATCH 11/21] update _send_init to use BM1366_set_nonce_space --- components/bm1397/bm1366.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/components/bm1397/bm1366.c b/components/bm1397/bm1366.c index 855760885..aa041383c 100644 --- a/components/bm1397/bm1366.c +++ b/components/bm1397/bm1366.c @@ -525,8 +525,9 @@ static uint8_t _send_init(uint64_t frequency) BM1366_send_hash_frequency(frequency); - unsigned char init794[11] = {0x55, 0xAA, 0x51, 0x09, 0x00, 0x10, 0x00, 0x00, 0x15, 0x1C, 0x02}; - _send_simple(init794, 11); + //Reg 0x10 used to be set to {0x55, 0xAA, 0x51, 0x09, 0x00, 0x10, 0x00, 0x00, 0x15, 0x1C, 0x02} + uint32_t full_nonce_scope = 0x151c * 128; + BM1366_set_nonce_scope(full_nonce_scope / chip_counter); unsigned char init795[11] = {0x55, 0xAA, 0x51, 0x09, 0x00, 0xA4, 0x90, 0x00, 0xFF, 0xFF, 0x1C}; _send_simple(init795, 11); From 5666d8cd6150f42e74082ffeda1cf2990bc7326b Mon Sep 17 00:00:00 2001 From: Dirk Moeller Date: Sat, 27 Apr 2024 11:01:16 +0000 Subject: [PATCH 12/21] update unit test --- components/bm1397/test/test_bm1366.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/components/bm1397/test/test_bm1366.c b/components/bm1397/test/test_bm1366.c index 9943be1a6..aab3080f9 100644 --- a/components/bm1397/test/test_bm1366.c +++ b/components/bm1397/test/test_bm1366.c @@ -147,25 +147,25 @@ TEST_CASE("Testing one single BM1366 chip against a known valid block", "[bm1366 // set difficulty mask (*GLOBAL_STATE.ASIC_functions.set_difficulty_mask_fn)(notify_message.difficulty); - task_result * asic_result = NULL; + // uncomment the lines below to simulate 4 chips / 4 nonce ranges + // chips_detected = 4; + // uint32_t magic_number_full_nonce_scope = 0x151c * 128; + // BM1366_set_nonce_scope(magic_number_full_nonce_scope / chips_detected); // Why do we need to change the chip address? see https://youtu.be/6o92HhvOc1I?t=5710 for a more detailed explanation. - // It seems that the chip (each chip address) has a different nonce space and - // in order to cover the whole nonce space, we need to have 128 chips (chip address 0-127). - // So we need to change the chip address to selecct the correct nonce space. - // The solution for block #839900 (the block we are using in this test) should be in nonce space of chip address 0xc2. - // In order to show and proof the different nonce spaces per chip address, we start at 96 (96 * 2 = 192 = 0xc0). - // It is expected to not find a solution in nonce space of chip address 0xc0. - // This unit test is designed to test one single BM1366 chip. - for (uint8_t i = 96; i < 128; i++) { - - uint8_t chip_address = i * 2; + // Each chip (each chip address) has a different nonce space (see BM1366_set_nonce_scope). + // So we need to change the chip address to simulate multible chips (and to select a nonce space by doing so). + // This unit test is designed to test one single BM1366 chip and has an option to simulate multible chips by changing the chip address. + task_result * asic_result = NULL; + for (uint16_t i = 0; i < 256; i = i + (256/chips_detected)) { + + uint8_t chip_address = i; ESP_LOGI(TAG, "Changing chip address and sending job; new chip address: 0x%02x", chip_address); - BM1366_set_chip_address(chip_address); + BM1366_set_single_chip_address(chip_address); (*GLOBAL_STATE.ASIC_functions.send_work_fn)(&GLOBAL_STATE, &job); - ESP_LOGI(TAG, "Waiting for result ... (might take a while due to 60s timeout)"); + ESP_LOGI(TAG, "Waiting for result ... (might take a while)"); asic_result = (*GLOBAL_STATE.ASIC_functions.receive_result_fn)(&GLOBAL_STATE); if (asic_result == NULL) { continue; } @@ -183,7 +183,7 @@ TEST_CASE("Testing one single BM1366 chip against a known valid block", "[bm1366 nonce = asic_result->nonce; double nonce_diff = test_nonce_value(&job, asic_result->nonce, asic_result->rolled_version); - ESP_LOGI(TAG, "Result[%d]: Nonce %lu (0x%08lx) Nonce difficulty %.32f. rolled-version 0x%08lx", counter, asic_result->nonce, asic_result->nonce, nonce_diff, asic_result->rolled_version); + ESP_LOGI(TAG, "Result[%d]: Nonce %lu (0x%08lx), Nonce difficulty %.32f, rolled-version 0x%08lx", counter, asic_result->nonce, asic_result->nonce, nonce_diff, asic_result->rolled_version); if (asic_result->nonce == expected_nonce && asic_result->rolled_version == expected_version) { ESP_LOGI(TAG, "Expected nonce and version match. Solution found!"); From 02c4b5fda67a373cb2076f374bbf455134040d77 Mon Sep 17 00:00:00 2001 From: Dirk Moeller Date: Sat, 27 Apr 2024 20:37:47 +0000 Subject: [PATCH 13/21] Not ready for prime time - Revert "update _send_init to use BM1366_set_nonce_space" This reverts commit d9f26b14f3e21c211863d641c5679307e04a7241. --- components/bm1397/bm1366.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/components/bm1397/bm1366.c b/components/bm1397/bm1366.c index aa041383c..855760885 100644 --- a/components/bm1397/bm1366.c +++ b/components/bm1397/bm1366.c @@ -525,9 +525,8 @@ static uint8_t _send_init(uint64_t frequency) BM1366_send_hash_frequency(frequency); - //Reg 0x10 used to be set to {0x55, 0xAA, 0x51, 0x09, 0x00, 0x10, 0x00, 0x00, 0x15, 0x1C, 0x02} - uint32_t full_nonce_scope = 0x151c * 128; - BM1366_set_nonce_scope(full_nonce_scope / chip_counter); + unsigned char init794[11] = {0x55, 0xAA, 0x51, 0x09, 0x00, 0x10, 0x00, 0x00, 0x15, 0x1C, 0x02}; + _send_simple(init794, 11); unsigned char init795[11] = {0x55, 0xAA, 0x51, 0x09, 0x00, 0xA4, 0x90, 0x00, 0xFF, 0xFF, 0x1C}; _send_simple(init795, 11); From 0d928054c2518d7402f44b4639cb9614cf23be16 Mon Sep 17 00:00:00 2001 From: Dirk Moeller Date: Sat, 27 Apr 2024 20:45:50 +0000 Subject: [PATCH 14/21] update unit test - new magic_number, call BM1366_set_nonce_scope in unit test --- components/bm1397/test/test_bm1366.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/bm1397/test/test_bm1366.c b/components/bm1397/test/test_bm1366.c index aab3080f9..e80c17019 100644 --- a/components/bm1397/test/test_bm1366.c +++ b/components/bm1397/test/test_bm1366.c @@ -147,10 +147,10 @@ TEST_CASE("Testing one single BM1366 chip against a known valid block", "[bm1366 // set difficulty mask (*GLOBAL_STATE.ASIC_functions.set_difficulty_mask_fn)(notify_message.difficulty); - // uncomment the lines below to simulate 4 chips / 4 nonce ranges + // uncomment the line below to simulate 4 chips / 4 nonce ranges // chips_detected = 4; - // uint32_t magic_number_full_nonce_scope = 0x151c * 128; - // BM1366_set_nonce_scope(magic_number_full_nonce_scope / chips_detected); + uint32_t magic_number_full_nonce_scope = 0xAFFFF; + BM1366_set_nonce_scope(magic_number_full_nonce_scope / chips_detected); // Why do we need to change the chip address? see https://youtu.be/6o92HhvOc1I?t=5710 for a more detailed explanation. // Each chip (each chip address) has a different nonce space (see BM1366_set_nonce_scope). @@ -173,7 +173,7 @@ TEST_CASE("Testing one single BM1366 chip against a known valid block", "[bm1366 uint32_t nonce = 0; int counter = 1; - while (asic_result != NULL && counter <= 100) { + while (asic_result != NULL && counter <= 150) { if (asic_result->rolled_version < version || (asic_result->rolled_version == version && asic_result->nonce == nonce)) { ESP_LOGI(TAG, "Rollover detected - Nonce %lu, Version 0x%08lx", asic_result->nonce, asic_result->rolled_version); From f5ead64d22d3e83b3c4885dff7c9ed6e0b0f45e1 Mon Sep 17 00:00:00 2001 From: Dirk Moeller Date: Sat, 27 Apr 2024 20:57:43 +0000 Subject: [PATCH 15/21] update BM1366_set_nonce_scope --- components/bm1397/bm1366.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/components/bm1397/bm1366.c b/components/bm1397/bm1366.c index 855760885..9aca460ee 100644 --- a/components/bm1397/bm1366.c +++ b/components/bm1397/bm1366.c @@ -584,7 +584,8 @@ void BM1366_set_single_chip_address(uint8_t new_address) _set_chip_address(new_address); } -void BM1366_set_nonce_scope(uint32_t chipmask) +// to be called like BM1366_set_nonce_scope( 0xAFFFF (magic number) / chips_detected ) +void BM1366_set_nonce_scope(uint32_t nonce_scope) { // 55 AA 51 09 00 10 00 00 11 5A 04 //s19kPro (77 chips) 0x115a //unsigned char command[9] = {0x00, 0x10, 0b00000000, 0b00000000, 0b00010001, 0b01011010}; @@ -598,11 +599,11 @@ void BM1366_set_nonce_scope(uint32_t chipmask) // convert into char array for (int i = 0; i < 4; i++) { - char value = (chipmask >> (8 * i)) & 0xFF; + char value = (nonce_scope >> (8 * i)) & 0xFF; command[5 - i] = value; } - ESP_LOGI(TAG, "Setting Nonce scope to %lu (0x%08lx)", chipmask, chipmask); + ESP_LOGI(TAG, "Setting Nonce scope to %lu (0x%08lx)", nonce_scope, nonce_scope); _send_BM1366((TYPE_CMD | GROUP_ALL | CMD_WRITE), command, 6, true); } From c012e05be66fd152a659406feed9c09bb9647b03 Mon Sep 17 00:00:00 2001 From: Dirk Moeller Date: Thu, 2 May 2024 18:16:40 +0000 Subject: [PATCH 16/21] add _calculate_chip_number, rev static chip_ccount and update BM1366_set_nonce_mask --- components/bm1397/bm1366.c | 105 ++++++++++++++++++++++----- components/bm1397/include/bm1366.h | 2 +- components/bm1397/test/test_bm1366.c | 3 +- 3 files changed, 88 insertions(+), 22 deletions(-) diff --git a/components/bm1397/bm1366.c b/components/bm1397/bm1366.c index 9aca460ee..cb4af7ca4 100644 --- a/components/bm1397/bm1366.c +++ b/components/bm1397/bm1366.c @@ -59,7 +59,6 @@ static const char * TAG = "bm1366Module"; static uint8_t asic_response_buffer[CHUNK_SIZE]; static task_result result; -static int chip_counter = 0; // updated in _send_init /// @brief /// @param ftdi @@ -447,7 +446,7 @@ static uint8_t _send_init(uint64_t frequency) unsigned char init3[7] = {0x55, 0xAA, 0x52, 0x05, 0x00, 0x00, 0x0A}; _send_simple(init3, 7); - chip_counter = 0; + int chip_counter = 0; while (true) { if(SERIAL_rx(asic_response_buffer, 11, 1000) > 0) { chip_counter++; @@ -557,6 +556,49 @@ static void _send_read_address(void) _send_BM1366((TYPE_CMD | GROUP_ALL | CMD_READ), read_address, 2, false); } +static int _calculate_chip_number(unsigned int actual_chip_count) +{ + int i = 0; + if(actual_chip_count == 1) + { + i = 1; + } + else if(actual_chip_count == 2) + { + i = 2; + } + else if((actual_chip_count > 2) && (actual_chip_count <= 4)) + { + i = 4; + } + else if((actual_chip_count > 4) && (actual_chip_count <= 8)) + { + i = 8; + } + else if((actual_chip_count > 8) && (actual_chip_count <= 16)) + { + i = 16; + } + else if((actual_chip_count > 16) && (actual_chip_count <= 32)) + { + i = 32; + } + else if((actual_chip_count > 32) && (actual_chip_count <= 64)) + { + i = 64; + } + else if((actual_chip_count > 64) && (actual_chip_count <= 128)) + { + i = 128; + } + else + { + ESP_LOGE(TAG,"actual_chip_count = %d, but it is error\n", actual_chip_count); + return -1; + } + return i; +} + uint8_t BM1366_init(uint64_t frequency) { ESP_LOGI(TAG, "Initializing BM1366"); @@ -584,27 +626,52 @@ void BM1366_set_single_chip_address(uint8_t new_address) _set_chip_address(new_address); } -// to be called like BM1366_set_nonce_scope( 0xAFFFF (magic number) / chips_detected ) -void BM1366_set_nonce_scope(uint32_t nonce_scope) +void BM1366_set_nonce_mask(int chip_count) { - // 55 AA 51 09 00 10 00 00 11 5A 04 //s19kPro (77 chips) 0x115a - //unsigned char command[9] = {0x00, 0x10, 0b00000000, 0b00000000, 0b00010001, 0b01011010}; - // 55 AA 51 09 00 10 00 00 14 46 04 //s19xp_luxos (110 chips) 0x1446 - //unsigned char command[9] = {0x00, 0x10, 0b00000000, 0b00000000, 0b00010100, 0b01000110}; - // 55 AA 51 09 00 10 00 00 15 1C 02 //s19xp-stock / BitaxeUltra 0x151c - //unsigned char command[9] = {0x00, 0x10, 0b00000000, 0b00000000, 0b00010101, 0b00011100}; - - // Default mask for 128 chips (address interval 0x02) on chain - unsigned char command[9] = {0x00, 0x10, 0x00, 0x00, 0x15, 0x1C}; - - // convert into char array + if (chip_count < 0) { chip_count = 0; } + if (chip_count > 128) { chip_count = 128; } + + chip_count = _calculate_chip_number(chip_count); // Because of the way the nonce ranges calculated, we need to use a fixed chip address interval (for now) + + // Every nonce returned by chip (except those sent by opencore) encodes address of the + // chip and core that computed it, because of the way they divide the search space. + + // uint8_t chip_address = (asic_result->nonce >> 9) & 0x7f; // Range 0x00-0xFF. Chip address seems to be 8 bits in size. However the first bit should always be 0 because the chip address is increment by 2. The last bit is always low for addresses < 0x80 and always high for addresses >= 0x80 + // uint8_t core_small_core_address = (asic_result->nonce >> 29) & 0x7; // Range 0x0-0x7. Helps to identify if the nonce was calculated by what small_core but not really important for now. + + // It seems the nonces calculation use the following structure: + // 31.................16 15..................0 + // 0byyy00000 0b0000000x 0bxxxxxxx0 0b00000000 // nonce calculated, one can compute the chip address and small core address from the nonce as outlines above + // 0b00000000 0b0000mmmm 0bmmmmmmm0 0b00000000 // nonce mask + // x = chip address (0x00 - 0xFF) + // y = small_core address (0x0 - 0x7) + // m = nonce mask used for nonce calculation. + + // The following are known configurations: + // 55 AA 51 09 00 10 00 00 11 5A 04 //s19kPro (77 chips) -> 0x115a + // unsigned char command[9] = {0x00, 0x10, 0b00000000, 0b00000000, 0b00010001, 0b01011010}; + // 55 AA 51 09 00 10 00 00 14 46 04 //s19xp_luxos (110 chips) -> 0x1446 + // unsigned char command[9] = {0x00, 0x10, 0b00000000, 0b00000000, 0b00010100, 0b01000110}; + // 55 AA 51 09 00 10 00 00 15 1C 02 //s19xp-stock / BitaxeUltra -> 0x151c + // unsigned char command[9] = {0x00, 0x10, 0b00000000, 0b00000000, 0b00010101, 0b00011100}; + // 55 AA 51 09 00 10 00 00 15 A4 0A //s21 (bm1368 - 108 chips) + // unsigned char command[9] = {0x00, 0x10, 0b00000000, 0b00000000, 0b00010101, 0b10100100}; + + // command template + unsigned char command[9] = {0x00, 0x10, 0x00, 0x00, 0x00, 0x00}; + + // This nonce_mask is used in combination with the chip address to calculate the nonce ranges for the chip. + uint32_t offset = (0x15FF / 2); // found by try-and-error. 15FF seems to be max value. Any higher number result in duplicated nonces because the way (using addr interval) I'm moving bits to the left. + uint32_t nonce_mask = offset * (0x100 / chip_count); + + // convert into char array and mix with command template for (int i = 0; i < 4; i++) { - char value = (nonce_scope >> (8 * i)) & 0xFF; - command[5 - i] = value; + char value = (nonce_mask >> (8 * i)) & 0xFF; + command[5 - i] = command[5 - i] | value; } - ESP_LOGI(TAG, "Setting Nonce scope to %lu (0x%08lx)", nonce_scope, nonce_scope); - _send_BM1366((TYPE_CMD | GROUP_ALL | CMD_WRITE), command, 6, true); + ESP_LOGI(TAG, "Setting Nonce mask to %08lX", nonce_mask); + _send_BM1366((TYPE_CMD | GROUP_ALL | CMD_WRITE), command, 6, false); } // Baud formula = 25M/((denominator+1)*8) diff --git a/components/bm1397/include/bm1366.h b/components/bm1397/include/bm1366.h index b8c87690b..de19a5267 100644 --- a/components/bm1397/include/bm1366.h +++ b/components/bm1397/include/bm1366.h @@ -41,6 +41,6 @@ int BM1366_set_default_baud(void); void BM1366_send_hash_frequency(float frequency); task_result * BM1366_proccess_work(void * GLOBAL_STATE); void BM1366_set_single_chip_address(uint8_t chipAddr); -void BM1366_set_nonce_scope(uint32_t chipmask); +void BM1366_set_nonce_mask(int chip_count); #endif /* BM1366_H_ */ \ No newline at end of file diff --git a/components/bm1397/test/test_bm1366.c b/components/bm1397/test/test_bm1366.c index e80c17019..b9fb006aa 100644 --- a/components/bm1397/test/test_bm1366.c +++ b/components/bm1397/test/test_bm1366.c @@ -149,8 +149,7 @@ TEST_CASE("Testing one single BM1366 chip against a known valid block", "[bm1366 // uncomment the line below to simulate 4 chips / 4 nonce ranges // chips_detected = 4; - uint32_t magic_number_full_nonce_scope = 0xAFFFF; - BM1366_set_nonce_scope(magic_number_full_nonce_scope / chips_detected); + BM1366_set_nonce_mask(chips_detected); // Why do we need to change the chip address? see https://youtu.be/6o92HhvOc1I?t=5710 for a more detailed explanation. // Each chip (each chip address) has a different nonce space (see BM1366_set_nonce_scope). From 0b3eb9d76d7b67ab1b86b8fd16aa044822383151 Mon Sep 17 00:00:00 2001 From: Dirk Moeller Date: Thu, 2 May 2024 18:17:52 +0000 Subject: [PATCH 17/21] update unit test - add isDuplicated check --- components/bm1397/test/test_bm1366.c | 55 +++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/components/bm1397/test/test_bm1366.c b/components/bm1397/test/test_bm1366.c index b9fb006aa..9e979707f 100644 --- a/components/bm1397/test/test_bm1366.c +++ b/components/bm1397/test/test_bm1366.c @@ -16,6 +16,44 @@ #include +typedef struct +{ + uint8_t chip_address; + uint32_t nonce; + uint16_t version; +} nonce_result; + +struct nonce_list { + nonce_result *data; + uint32_t numUnique; + uint32_t numDuplicated; + uint32_t size; +}; + +void initList(struct nonce_list *_list); +void initList(struct nonce_list *_list) { + _list->numUnique = 0; + _list->size = 10; + _list->data = malloc(_list->size * sizeof(nonce_result)); +} + +bool isDuplicated(struct nonce_list *_list, nonce_result _item); +bool isDuplicated(struct nonce_list *_list, nonce_result _item) { + if (_list->numUnique == _list->size) { + _list->size += 10; + _list->data = realloc( _list->data, _list->size * sizeof(nonce_result) ); + } + for (uint32_t j = 0; j < _list->numUnique; j++) { + if (_list->data[j].nonce == _item.nonce && _list->data[j].version == _item.version) { + _list->numDuplicated++; + return true; + } + } + _list->data[_list->numUnique] = _item; + _list->numUnique++; + return false; +} + static GlobalState GLOBAL_STATE = {.extranonce_str = NULL, .extranonce_2_len = 0, .abandon_work = 0, .version_mask = 0}; static const char * TAG = "test_bm1366"; @@ -150,6 +188,8 @@ TEST_CASE("Testing one single BM1366 chip against a known valid block", "[bm1366 // uncomment the line below to simulate 4 chips / 4 nonce ranges // chips_detected = 4; BM1366_set_nonce_mask(chips_detected); + struct nonce_list nonceList; + initList(&nonceList); // Why do we need to change the chip address? see https://youtu.be/6o92HhvOc1I?t=5710 for a more detailed explanation. // Each chip (each chip address) has a different nonce space (see BM1366_set_nonce_scope). @@ -181,9 +221,18 @@ TEST_CASE("Testing one single BM1366 chip against a known valid block", "[bm1366 version = asic_result->rolled_version; nonce = asic_result->nonce; - double nonce_diff = test_nonce_value(&job, asic_result->nonce, asic_result->rolled_version); - ESP_LOGI(TAG, "Result[%d]: Nonce %lu (0x%08lx), Nonce difficulty %.32f, rolled-version 0x%08lx", counter, asic_result->nonce, asic_result->nonce, nonce_diff, asic_result->rolled_version); + // Every nonce returned by chip (except those sent by opencore) encodes address of the + // chip and core that computed it, because of the way they divide the search space. + uint8_t chipAddr = (asic_result->nonce >> 9) & 0x7f; + uint8_t coreAddr = (asic_result->nonce >> 29) & 0x7; + double nonce_diff = test_nonce_value(&job, asic_result->nonce, asic_result->rolled_version); + char * result_isDuplicated = ""; + if ( isDuplicated(&nonceList, (nonce_result) {.nonce = asic_result->nonce, .version = asic_result->rolled_version, .chip_address = chip_address}) ) { + result_isDuplicated = "(duplicate)"; + } + ESP_LOGI(TAG, "Result[%d](%02x/%02x): Nonce %lu (0x%08lx), Nonce difficulty %.32f. rolled-version 0x%08lx %s", counter, chipAddr, coreAddr, asic_result->nonce, asic_result->nonce, nonce_diff, asic_result->rolled_version, result_isDuplicated); + /* if (asic_result->nonce == expected_nonce && asic_result->rolled_version == expected_version) { ESP_LOGI(TAG, "Expected nonce and version match. Solution found!"); break; @@ -196,9 +245,11 @@ TEST_CASE("Testing one single BM1366 chip against a known valid block", "[bm1366 break; } } + ESP_LOGI(TAG, "%lu unique nonces, %lu duplicates.", nonceList.numUnique, nonceList.numDuplicated); free(GLOBAL_STATE.ASIC_TASK_MODULE.active_jobs); free(GLOBAL_STATE.valid_jobs); + free(nonceList.data); // turn ASIC off gpio_set_direction(GPIO_NUM_10, GPIO_MODE_OUTPUT); From dba4eb61db8d5b463bd7a54b8e138c92c79c2ac1 Mon Sep 17 00:00:00 2001 From: Dirk Moeller Date: Thu, 2 May 2024 18:18:59 +0000 Subject: [PATCH 18/21] update unit test - add time measurement --- components/bm1397/test/test_bm1366.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/components/bm1397/test/test_bm1366.c b/components/bm1397/test/test_bm1366.c index 9e979707f..33cdb2340 100644 --- a/components/bm1397/test/test_bm1366.c +++ b/components/bm1397/test/test_bm1366.c @@ -188,23 +188,30 @@ TEST_CASE("Testing one single BM1366 chip against a known valid block", "[bm1366 // uncomment the line below to simulate 4 chips / 4 nonce ranges // chips_detected = 4; BM1366_set_nonce_mask(chips_detected); + + struct timeval begin, end; struct nonce_list nonceList; initList(&nonceList); + task_result * asic_result = NULL; // Why do we need to change the chip address? see https://youtu.be/6o92HhvOc1I?t=5710 for a more detailed explanation. // Each chip (each chip address) has a different nonce space (see BM1366_set_nonce_scope). // So we need to change the chip address to simulate multible chips (and to select a nonce space by doing so). // This unit test is designed to test one single BM1366 chip and has an option to simulate multible chips by changing the chip address. - task_result * asic_result = NULL; for (uint16_t i = 0; i < 256; i = i + (256/chips_detected)) { uint8_t chip_address = i; ESP_LOGI(TAG, "Changing chip address and sending job; new chip address: 0x%02x", chip_address); BM1366_set_single_chip_address(chip_address); + + vTaskDelay(1000 / portTICK_PERIOD_MS); + SERIAL_clear_buffer(); + (*GLOBAL_STATE.ASIC_functions.send_work_fn)(&GLOBAL_STATE, &job); ESP_LOGI(TAG, "Waiting for result ... (might take a while)"); + gettimeofday(&begin, 0); asic_result = (*GLOBAL_STATE.ASIC_functions.receive_result_fn)(&GLOBAL_STATE); if (asic_result == NULL) { continue; } @@ -241,6 +248,11 @@ TEST_CASE("Testing one single BM1366 chip against a known valid block", "[bm1366 asic_result = (*GLOBAL_STATE.ASIC_functions.receive_result_fn)(&GLOBAL_STATE); // wait for next result counter++; } + gettimeofday(&end, 0); + ESP_LOGI(TAG, "Elapsed: %f seconds", (double)(end.tv_sec - begin.tv_sec)+(end.tv_usec - begin.tv_usec)*1e-6 ); + ESP_LOGI(TAG, "----------------------------------"); + + /* if (asic_result != NULL && asic_result->nonce == expected_nonce) { break; } From 6cd0314caa0af840bef4757c9c76cadd187d33c3 Mon Sep 17 00:00:00 2001 From: Dirk Moeller Date: Thu, 2 May 2024 18:20:45 +0000 Subject: [PATCH 19/21] update unit test - minor updates --- components/bm1397/test/test_bm1366.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/components/bm1397/test/test_bm1366.c b/components/bm1397/test/test_bm1366.c index 33cdb2340..a1c80f744 100644 --- a/components/bm1397/test/test_bm1366.c +++ b/components/bm1397/test/test_bm1366.c @@ -185,7 +185,7 @@ TEST_CASE("Testing one single BM1366 chip against a known valid block", "[bm1366 // set difficulty mask (*GLOBAL_STATE.ASIC_functions.set_difficulty_mask_fn)(notify_message.difficulty); - // uncomment the line below to simulate 4 chips / 4 nonce ranges + // uncomment the lines below to simulate 4 chips / 4 nonce ranges // chips_detected = 4; BM1366_set_nonce_mask(chips_detected); @@ -195,7 +195,7 @@ TEST_CASE("Testing one single BM1366 chip against a known valid block", "[bm1366 task_result * asic_result = NULL; // Why do we need to change the chip address? see https://youtu.be/6o92HhvOc1I?t=5710 for a more detailed explanation. - // Each chip (each chip address) has a different nonce space (see BM1366_set_nonce_scope). + // Each chip (each chip address) has a different nonce space (see BM1366_set_nonce_mask). // So we need to change the chip address to simulate multible chips (and to select a nonce space by doing so). // This unit test is designed to test one single BM1366 chip and has an option to simulate multible chips by changing the chip address. for (uint16_t i = 0; i < 256; i = i + (256/chips_detected)) { @@ -216,12 +216,12 @@ TEST_CASE("Testing one single BM1366 chip against a known valid block", "[bm1366 if (asic_result == NULL) { continue; } uint32_t version = asic_result->rolled_version; - uint32_t nonce = 0; + uint32_t nonce = asic_result->nonce; int counter = 1; - while (asic_result != NULL && counter <= 150) { + while (asic_result != NULL && counter <= 1000) { - if (asic_result->rolled_version < version || (asic_result->rolled_version == version && asic_result->nonce == nonce)) { + if (asic_result->rolled_version < version || (counter > 1 && asic_result->rolled_version == version && asic_result->nonce == nonce)) { ESP_LOGI(TAG, "Rollover detected - Nonce %lu, Version 0x%08lx", asic_result->nonce, asic_result->rolled_version); break; } @@ -269,5 +269,6 @@ TEST_CASE("Testing one single BM1366 chip against a known valid block", "[bm1366 TEST_ASSERT_NOT_NULL(asic_result); TEST_ASSERT_EQUAL_UINT32(expected_nonce, asic_result->nonce); + TEST_ASSERT_EQUAL_UINT32(expected_version, asic_result->rolled_version); } From 0cef4d6dc21d5a207c82178ff528207593430ac0 Mon Sep 17 00:00:00 2001 From: Dirk Moeller Date: Thu, 2 May 2024 18:38:41 +0000 Subject: [PATCH 20/21] update unit test - fix typo and remove option to show chip/core address in log as it might be confusion. --- components/bm1397/test/test_bm1366.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/components/bm1397/test/test_bm1366.c b/components/bm1397/test/test_bm1366.c index a1c80f744..1453738b7 100644 --- a/components/bm1397/test/test_bm1366.c +++ b/components/bm1397/test/test_bm1366.c @@ -228,18 +228,13 @@ TEST_CASE("Testing one single BM1366 chip against a known valid block", "[bm1366 version = asic_result->rolled_version; nonce = asic_result->nonce; - // Every nonce returned by chip (except those sent by opencore) encodes address of the - // chip and core that computed it, because of the way they divide the search space. - uint8_t chipAddr = (asic_result->nonce >> 9) & 0x7f; - uint8_t coreAddr = (asic_result->nonce >> 29) & 0x7; - double nonce_diff = test_nonce_value(&job, asic_result->nonce, asic_result->rolled_version); char * result_isDuplicated = ""; if ( isDuplicated(&nonceList, (nonce_result) {.nonce = asic_result->nonce, .version = asic_result->rolled_version, .chip_address = chip_address}) ) { result_isDuplicated = "(duplicate)"; } - ESP_LOGI(TAG, "Result[%d](%02x/%02x): Nonce %lu (0x%08lx), Nonce difficulty %.32f. rolled-version 0x%08lx %s", counter, chipAddr, coreAddr, asic_result->nonce, asic_result->nonce, nonce_diff, asic_result->rolled_version, result_isDuplicated); - /* + ESP_LOGI(TAG, "Result[%d]: Nonce %lu (0x%08lx), Nonce difficulty %.32f. rolled-version 0x%08lx %s", counter, asic_result->nonce, asic_result->nonce, nonce_diff, asic_result->rolled_version, result_isDuplicated); + if (asic_result->nonce == expected_nonce && asic_result->rolled_version == expected_version) { ESP_LOGI(TAG, "Expected nonce and version match. Solution found!"); break; @@ -252,12 +247,12 @@ TEST_CASE("Testing one single BM1366 chip against a known valid block", "[bm1366 ESP_LOGI(TAG, "Elapsed: %f seconds", (double)(end.tv_sec - begin.tv_sec)+(end.tv_usec - begin.tv_usec)*1e-6 ); ESP_LOGI(TAG, "----------------------------------"); - /* if (asic_result != NULL && asic_result->nonce == expected_nonce) { break; } } ESP_LOGI(TAG, "%lu unique nonces, %lu duplicates.", nonceList.numUnique, nonceList.numDuplicated); + ESP_LOGI(TAG, "----------------------------------"); free(GLOBAL_STATE.ASIC_TASK_MODULE.active_jobs); free(GLOBAL_STATE.valid_jobs); From 3f3da6f39d979072c880d4b01a7d91c1e6b619b1 Mon Sep 17 00:00:00 2001 From: Dirk Moeller Date: Thu, 2 May 2024 19:17:31 +0000 Subject: [PATCH 21/21] fix typo --- components/bm1397/bm1366.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bm1397/bm1366.c b/components/bm1397/bm1366.c index cb4af7ca4..ebd772cb1 100644 --- a/components/bm1397/bm1366.c +++ b/components/bm1397/bm1366.c @@ -628,7 +628,7 @@ void BM1366_set_single_chip_address(uint8_t new_address) void BM1366_set_nonce_mask(int chip_count) { - if (chip_count < 0) { chip_count = 0; } + if (chip_count < 1) { chip_count = 1; } if (chip_count > 128) { chip_count = 128; } chip_count = _calculate_chip_number(chip_count); // Because of the way the nonce ranges calculated, we need to use a fixed chip address interval (for now)