Dla kogo to jest
Maszyna, która i tak stoi — NAS, Raspberry, mały domowy serwer, skrzynka w szafie, za którą już płacisz — z gigabajtem lub więcej miejsca, którego nie potrzebujesz, w tym samym LAN-ie co node Sensmos. Linux z Pythonem 3, nic do instalowania poza samym skryptem. Root jest potrzebny tylko do zapisania pliku stanu i jednostki systemd.
Kupującym jest zawsze inny właściciel noda: Store to handel wewnętrzny między ludźmi, którzy mają nody, nie publiczna chmura. Z kupującym nie masz do czynienia bezpośrednio; serwer dobiera sprzedawców, przenosi bajty i rozlicza dni.
Co naprawdę trzymasz
Zaszyfrowane bloby. Apka kupującego szyfruje każdy plik na telefonie kluczem wyprowadzonym z podpisu jego portfela; do Ciebie dociera szyfrogram z losowym identyfikatorem. Nie dostajesz klucza, nazwy pliku ani niczego, co wskazuje kupującego. Po Twojej stronie nie ma ścieżki w kodzie, która mogłaby cokolwiek odszyfrować — agent to jeden czytelny plik, sprawdź sam.
Od store-py/0.2 obok każdego bloba leży mały plik .meta: zapakowany klucz pliku, zaszyfrowana nazwa, rozmiary i skróty bloków, podpisane portfelem kupującego. Nic to nie zmienia w tym, co możesz odczytać — klucz w środku jest zapieczętowany do kupującego i nikomu innemu się nie przyda. Istnieje po to, żeby pliki przeżyły nas: do tej pory te dane leżały wyłącznie w bazie serwera, a jej utrata znaczyłaby utratę plików, mimo że bajty żyją na twoim dysku. Rekord wędruje razem z bajtami, więc druga kopia niesie identyczny.
Szybki start
Uruchom to na maszynie, która będzie trzymać dane. Raz rozmawia z Twoim nodem po LAN-ie, potem już tylko z serwerem.
# 1 — pobierz agenta (jeden plik, tylko biblioteka standardowa)
sudo curl -fsSL -o /usr/local/bin/sensmos-store.py https://sensmos.com/ext/sensmos-store.py
sudo chmod +x /usr/local/bin/sensmos-store.py
# 2 — sparuj przez noda: jego adres w LAN-ie, jego PIN, etykieta, gdzie trzymać bloby, ile oferujesz
sudo sensmos-store.py --pair 192.168.1.50 --pin 123456 --name "NAS w piwnicy" \
--dir /srv/sensmos-store --capacity 100G
# 3 — zainstaluj i uruchom jako usługę startującą z systemem
sudo sensmos-store.py --install-service
# 4 — patrz
journalctl -u sensmos-store -f
Parowanie wypisuje OK — attachment …, token saved to /etc/sensmos-store.json. W logu usługi widać potem:
21:14:02 store agent store-py/0.3 dir=/srv/sensmos-store capacity=100 GB used=0.00 GB
21:14:03 connected as 3f9a1c2e
Od tej chwili jesteś w puli. Pierwszy kupujący pokaże się w logu jako put 7d0b… 18.1 MB …, a po nim put 7d0b… done; dowody jako proof 7d0b… block 3: answered (10 MB hashed).
Adres noda w LAN-ie znajdziesz na liście klientów routera; PIN to PIN noda z apki. Node musi być w chwili parowania online (połączony z serwerem) — przekazuje Twoją prośbę i odpowiedź serwera.
Jak dostajesz zapłatę
| co | warunki |
|---|---|
| cena | 0,1 GALU za GB za kopię na dobę — kupujący wybiera rozmiar, od 1 GB w górę, i może go potem zmieniać po 1 GB; 10 GB to 1 GALU dziennie za kopię |
| Twój udział | 70%; 30% wraca do puli nagród |
| płatne za | każdy dzień, w którym pakiet kupującego jest przypięty do Ciebie, a Ty byłeś na miejscu: gdy jego pliki leżą na Twoim dysku, kopia zaliczyła dowód; gdy pakiet jest jeszcze pusty, agent meldował się tego dnia — miejsce jest zarezerwowane tak czy inaczej |
| niepłatne za | dni offline albo z oblanym dowodem; dni, w których kupujący nie miał GALU — taki dzień liczy się kupującemu jako zaległość (wysyłki wstrzymane, po 14 dobach kopie zwolnione), a Ty za niego nie dostajesz zapłaty |
Rozliczenie idzie na serwerze raz na godzinę i księguje każdą trójkę (dzień, kupujący, sprzedawca) raz. GALU ląduje w saldzie Twojego portfela jak każdy inny przychód z usług.
Dowody — skąd serwer wie, że dalej masz plik
Trzy razy dziennie na kopię serwer wybiera losowy blok 10 MB losowego pliku, który trzymasz, i wysyła sól. Twój agent liczy skrót bloku z solą i odpowiada 32 bajtami — żadne dane nie idą, po naszej stronie nic nie jest liczone. Przy dwóch kopiach u dwóch sprzedawców obie odpowiedzi porównywane są ze sobą. Gdy się różnią albo gdy online jest tylko jedna kopia, serwer prosi o surowy blok i sprawdza go z listą skrótów, którą kupujący przysłał przy wysyłce.
Trzy oblane dowody z rzędu i kopia dostaje status zrzuconej: koniec wyzwań, koniec zapłaty. Innej kary nie ma — po prostu przestajesz na niej zarabiać.
Pojemność i dobór sprzedawców
--capacityto Twoja oferta. Nie jest sprawdzana — kto zadeklaruje więcej, niż ma, obleje dowody i nic nie zarobi, i to jest cała kontrola.- Liczy się wolne miejsce w księdze serwera (co u Ciebie umieścił), nie meldunek agenta; raport co pięć minut jest informacyjny.
- Kupujący wybiera rozmiar pakietu przy zakupie — dowolną pełną liczbę gigabajtów, ograniczoną tym, ile sprzedawcy mają naprawdę wolnego — a potem dokupuje albo zmniejsza po gigabajcie u tych samych sprzedawców. Każdy pełny wolny gigabajt Twojej oferty da się sprzedać.
- Sprzedawcy są szeregowani po wolnym miejscu; dwie kopie kupującego idą zawsze do dwóch różnych właścicieli i nigdy na maszyny samego kupującego.
- Raz wybrany jesteś przypięty: każdy plik, który ten kupujący od tej chwili wyśle, ląduje u Ciebie, a gdy dokupi gigabajt, musi się on zmieścić u Ciebie. Może też zmniejszać pakiet po gigabajcie, do tego, ile zajmują jego pliki. Jego pakiet sam nigdzie się nie przenosi. Kupujący może go w każdej chwili zamknąć: jego pliki znikają z Twojego dysku, miejsce jest znów wolne, a opłaty kończą się z tym dniem.
Żeby zmienić ofertę, popraw capacity_b w /etc/sensmos-store.json i zrestartuj usługę. Żeby przestać sprzedawać, zatrzymaj usługę — bez dowodów Twoje kopie zostaną zrzucone w ciągu doby i wypadasz z puli; bloby w --dir możesz skasować.
Sieć
Agent łączy się wychodząco z sensmos.com po TLS i trzyma to jedno połączenie. Sterowanie — który plik trzymać, który blok udowodnić, co skasować — przychodzi zawsze nim, i to działa za CGNAT bez portu przychodzącego.
Bajty plików to osobna sprawa. Idą wprost między tobą a właścicielem pliku, gdy tylko do jednego z was da się zadzwonić:
- da się do ciebie — urządzenie właściciela łączy się z twoim portem i plik idzie bezpośrednio;
- da się do niego — to ty dzwonisz do niego;
- do nikogo — bajty idą przez serwer, tak jak dotąd.
Którą z trzech, decyduje serwer, za każdym razem od nowa, i sprawdza osiągalność tuż przed transferem. Adres, który działał godzinę temu, nie dowodzi niczego: telefony zmieniają sieci, a przekierowania na routerach znikają po restarcie. Agent nigdy nie wybiera trasy sam.
Port, na którym nasłuchuje (domyślnie 9033), odpowiada na każde połączenie jedną linią z nazwą agenta. Tak samo mierzona jest osiągalność — serwer dzwoni pod ten port sam, bo sprzedawców przekonanych, że mają publiczny adres, choć go nie mają, jest zbyt wielu, żeby wierzyć deklaracji. Jeśli twój router umie UPnP, port zostanie przekierowany automatycznie; --no-upnp, jeśli wolisz zrobić to po swojemu, --no-direct, żeby nie nasłuchiwać wcale.
13:16:55 direct: listening on TCP 9033
13:21:55 direct_ok: Reachable from the internet at 203.0.113.9:9033.
13:24:03 direct recv 8f2a1c7d with 198.51.100.4: ok (12.4 MB)
Host, do którego nie da się zadzwonić, sprzedaje dokładnie tak jak dotąd — jego bajty po prostu idą trzecią trasą.
Co sprawdzasz
Każdy bajt, który odbierasz, jest liczony w locie i porównywany z rekordem, który właściciel podpisał, zanim plik w ogóle opuścił jego urządzenie: blok po bloku, a na koniec całość. Plik, który się nie zgadza, nie powstaje — zgłaszasz zły blok i nic nie ląduje na twoim dysku.
To chroni ciebie, nie nas. Uszkodzona wysyłka stawała się dotąd twoim problemem: plik leżał, oblewał dobowy dowód i kosztował cię zapłatę za cudzy błąd. Teraz zostaje odrzucony na wejściu. Sprawdzenie działa na wszystkich trzech trasach, także przy kopiach ściąganych z innego hosta.
Gdzie to widać
W apce (1.5.60 lub nowszej), na karcie noda, który ręczy za agenta, w sekcji Dodatki: online czy nie, oferowane i zajęte miejsce, ile kopii leży, dowody z ostatnich siedmiu dni, zarobek. Długie przytrzymanie odłącza agenta (token jest odbierany od razu). Log usługi ma to samo, linijka po linijce.
Flagi
| flaga | znaczenie |
|---|---|
--pair IP --pin PIN --name "…" | jednorazowe parowanie przez noda |
--dir DIR | gdzie trzymane są bloby (domyślnie /var/lib/sensmos-store) |
--capacity 100G | oferowane miejsce; przyrostki M, G, T |
--install-service | kopia do /usr/local/bin, zapis i włączenie jednostki systemd |
--be URL | inny serwer, do testów |
--direct-port 9033 | port przychodzący odpowiadający linią powitalną agenta |
--no-direct | nie nasłuchuj na żadnym porcie |
--no-upnp | nie proś routera o przekierowanie tego portu (domyślnie prosi i odnawia w trakcie pracy) |
Te trzy ustawienia są zapisywane do /etc/sensmos-store.json, po czym program kończy działanie — usługa uruchamia skrypt bez argumentów, więc podaj je raz i zrestartuj ją.
Jednostka, którą zapisuje:
# /etc/systemd/system/sensmos-store.service
[Unit]
Description=Sensmos store agent
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/usr/bin/python3 /usr/local/bin/sensmos-store.py
Restart=always
RestartSec=10
User=root
[Install]
WantedBy=multi-user.target
Parowanie — token
Agent nie ma własnych poświadczeń. Prosi Twojego noda (PIN-em noda, z wnętrza LAN-u), żeby za niego poręczył; node przekazuje prośbę do serwera, a serwer wydaje token o zakresie store.serve — obsługa sesji Store, nic więcej. Token leży w /etc/sensmos-store.json (prawa 0600) i agent odnawia go sam. Jeden node może poręczyć za najwyżej cztery przystawki. Pełny kontrakt jest na stronie Przystawki i EXT API.
Aktualizacje
Agent nigdy nie aktualizuje się sam: działa jako root w Twoim LAN-ie, a serwer, który mógłby wgrać mu kod, byłby drogą do Twojej sieci. Żeby zaktualizować, powtórz krok 1 i zrestartuj:
sudo curl -fsSL -o /usr/local/bin/sensmos-store.py https://sensmos.com/ext/sensmos-store.py
sudo systemctl restart sensmos-store
Od store-py/0.4 pliki idą bezpośrednio, a to, co odbierasz, jest sprawdzane. Starszy skrypt dalej sprzedaje, dowodzi i zarabia, ale każdy bajt przechodzi u niego przez serwer, a uszkodzony plik przyjmie bez mrugnięcia. Apka pokazuje na kafelku sprzedawcy, gdy jest nowsza wersja.
Od store-py/0.5 przerwany transfer wznawia się zamiast zaczynać od początku. Gdy łącze padnie w połowie pliku, odebrana część zostaje na dysku, a następna próba rusza właśnie od tego miejsca — tak samo w obie strony i tak samo przy odbudowie kopii między hostami. Oddajesz wyłącznie tę część, którą sam sprawdziłeś, więc wznowiony plik jest weryfikowany dokładnie tak samo surowo jak ten, który przyszedł za jednym razem.
Aktualizacja niczego ci nie zabiera. Pliki, które już trzymasz, układ na dysku, codzienny dowód i twój zarobek zostają nietknięte — 0.5 czyta je i odpowiada za nie dokładnie tak jak 0.4. Niedokończony kawałek to przestrzeń robocza, nigdy przechowywane dane: znika w chwili, gdy właściciel odwoła wysyłkę, albo po tygodniu, jeśli nikt po niego nie wróci — i tak, i tak nic za niego nie płacisz i nic z niego nie zarabiasz.
Nieaktualny agent przestaje dostawać nowe pliki. Od store-py/0.2 agent zapisuje opisany wyżej rekord .meta; skrypt, który tego nie potrafi, wypada z doboru sprzedawców — dalej serwuje i dowodzi to, co już ma, ale nic nowego do niego nie trafia. Apka mówi o tym na kaflu sprzedawcy, a log przy każdym połączeniu.
Początki
Store jest nowy, a pula mała. Jeśli postawisz sprzedawcę i przez jakiś czas nic nie przychodzi, to uczciwy stan popytu, nie błąd po Twojej stronie — odezwij się na Discordzie, a powiemy, jak wygląda pula.