1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
#include "test_framework.h"
#include "../../main/config.h"
#include "../../main/identity.h"
#include <string.h>
#include <stdio.h>
#include <mbedtls/sha256.h>
#include "../../main/beacon_price.h"
static tollgate_config_t g_test_config;
static tollgate_identity_t g_test_identity;
const tollgate_config_t *tollgate_config_get(void) { return &g_test_config; }
const tollgate_identity_t *identity_get(void) { return &g_test_identity; }
int main(void)
{
printf("=== test_beacon_price ===\n");
memset(&g_test_config, 0, sizeof(g_test_config));
strncpy(g_test_config.mint_url, "https://testnut.cashu.space", sizeof(g_test_config.mint_url) - 1);
strncpy(g_test_config.metric, "milliseconds", sizeof(g_test_config.metric) - 1);
g_test_config.price_per_step = 21;
g_test_config.step_size_ms = 60000;
strncpy(g_test_config.nostr_geohash, "u281w0dfz", sizeof(g_test_config.nostr_geohash) - 1);
memset(&g_test_identity, 0, sizeof(g_test_identity));
strncpy(g_test_identity.npub_hex, "abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890", 64);
g_test_identity.initialized = true;
printf("\n--- tollgate_price_payload_t size ---\n");
{
ASSERT_EQ_INT(26, (int)TOLLGATE_IE_PAYLOAD_SIZE, "payload is 26 bytes");
ASSERT_EQ_INT(32, (int)TOLLGATE_IE_TOTAL_SIZE, "total IE is 32 bytes");
}
printf("\n--- beacon_price_hash_mint ---\n");
{
uint8_t hash[4];
beacon_price_hash_mint("https://testnut.cashu.space", hash);
uint8_t expected[32];
mbedtls_sha256((const unsigned char *)"https://testnut.cashu.space",
strlen("https://testnut.cashu.space"), expected, 0);
ASSERT_MEM_EQ(expected, hash, 4, "mint_hash matches SHA-256 prefix");
uint8_t hash2[4];
beacon_price_hash_mint("https://other.mint.url", hash2);
ASSERT(memcmp(hash, hash2, 4) != 0, "different mint URLs produce different hashes");
}
printf("\n--- beacon_price_hash_npub ---\n");
{
uint8_t hash[4];
beacon_price_hash_npub("abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890", hash);
uint8_t expected[32];
mbedtls_sha256((const unsigned char *)"abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890",
64, expected, 0);
ASSERT_MEM_EQ(expected, hash, 4, "npub_hash matches SHA-256 prefix");
}
printf("\n--- beacon_price_build_ie (time metric) ---\n");
{
tollgate_price_ie_t ie;
beacon_price_build_ie(&ie);
ASSERT_EQ_INT(0xDD, ie.element_id, "element_id is 0xDD");
ASSERT_EQ_INT(4 + 26, ie.length, "length is 30 (4 header + 26 payload)");
ASSERT_EQ_INT(0xC0, ie.vendor_oui[0], "OUI byte 0");
ASSERT_EQ_INT(0xFF, ie.vendor_oui[1], "OUI byte 1");
ASSERT_EQ_INT(0xEE, ie.vendor_oui[2], "OUI byte 2");
ASSERT_EQ_INT(0x01, ie.vendor_oui_type, "OUI type is 0x01");
ASSERT_EQ_INT(1, ie.payload.version, "version is 1");
ASSERT_EQ_INT(0, ie.payload.metric, "metric is 0 (milliseconds)");
ASSERT_EQ_INT(21, ie.payload.price_per_step, "price is 21");
ASSERT_EQ_INT(60000, (int)ie.payload.step_size, "step_size is 60000");
uint8_t expected_mint_hash[4];
beacon_price_hash_mint("https://testnut.cashu.space", expected_mint_hash);
ASSERT_MEM_EQ(expected_mint_hash, ie.payload.mint_hash, 4, "mint_hash matches");
ASSERT_EQ_INT(9, ie.payload.geohash_len, "geohash_len is 9");
ASSERT(memcmp(ie.payload.geohash, "u281w0dfz", 9) == 0, "geohash matches");
}
printf("\n--- beacon_price_build_ie (bytes metric) ---\n");
{
strncpy(g_test_config.metric, "bytes", sizeof(g_test_config.metric) - 1);
g_test_config.step_size_bytes = 22020096;
g_test_config.price_per_step = 5;
tollgate_price_ie_t ie;
beacon_price_build_ie(&ie);
ASSERT_EQ_INT(1, ie.payload.metric, "metric is 1 (bytes)");
ASSERT_EQ_INT(5, ie.payload.price_per_step, "price is 5");
ASSERT_EQ_INT(22020096, (int)ie.payload.step_size, "step_size is 22020096 bytes");
strncpy(g_test_config.metric, "milliseconds", sizeof(g_test_config.metric) - 1);
g_test_config.step_size_ms = 60000;
g_test_config.price_per_step = 21;
}
printf("\n--- roundtrip: build → parse ---\n");
{
tollgate_price_ie_t ie;
beacon_price_build_ie(&ie);
vendor_ie_data_t *vnd_ie = (vendor_ie_data_t *)&ie;
ASSERT(vnd_ie->length >= 4 + (int)TOLLGATE_IE_PAYLOAD_SIZE, "vendor IE length sufficient");
const tollgate_price_payload_t *parsed = (const tollgate_price_payload_t *)vnd_ie->payload;
ASSERT_EQ_INT(1, parsed->version, "parsed version");
ASSERT_EQ_INT(0, parsed->metric, "parsed metric");
ASSERT_EQ_INT(21, parsed->price_per_step, "parsed price");
ASSERT_EQ_INT(60000, (int)parsed->step_size, "parsed step_size");
ASSERT_EQ_INT(9, parsed->geohash_len, "parsed geohash_len");
}
printf("\n--- struct packing check ---\n");
{
tollgate_price_ie_t ie;
memset(&ie, 0, sizeof(ie));
int expected_size = 2 + 3 + 1 + 26;
ASSERT_EQ_INT(expected_size, (int)sizeof(tollgate_price_ie_t), "no padding in struct");
}
TEST_SUMMARY();
}
|