Ograniczenia
Tworzenie programów na blockchainie Solana wiąże się z pewnymi wrodzonymi ograniczeniami. Poniżej znajduje się lista typowych ograniczeń, na które możesz natrafić.
Biblioteki Rust
Ponieważ programy on-chain oparte na języku Rust muszą działać deterministycznie w środowisku o ograniczonych zasobach i jednowątkowym, mają pewne ograniczenia dotyczące różnych bibliotek.
Programy on-chain w języku Rust obsługują większość bibliotek libstd, libcore i liballoc języka Rust, a także wiele bibliotek zewnętrznych (3rd party crates).
Istnieją pewne ograniczenia, ponieważ te programy działają w środowisku o ograniczonych zasobach, jednowątkowym i muszą być deterministyczne:
- Brak dostępu do:
rand
std::fs
std::net
std::future
std::process
std::sync
std::task
std::thread
std::time
- Ograniczony dostęp do:
std::hash
std::os
- Bincode jest niezwykle kosztowny obliczeniowo zarówno pod względem cykli, jak i głębokości wywołań, dlatego należy go unikać.
- Formatowanie ciągów znaków (string formatting) powinno być unikane, ponieważ jest również kosztowne obliczeniowo.
- Brak wsparcia dla
println!
,print!
, użyj makramsg!
zamiast. - Środowisko wykonawcze (runtime) narzuca limit liczby instrukcji, które program może wykonać podczas przetwarzania jednej instrukcji. Zobacz budżet obliczeniowy po więcej informacji.
Budżet obliczeniowy
Aby zapobiec nadużywaniu zasobów obliczeniowych blockchaina, każda transakcja ma przydzielony budżet obliczeniowy. Przekroczenie tego budżetu obliczeniowego spowoduje niepowodzenie transakcji.
Zobacz dokumentację ograniczeń obliczeniowych po bardziej szczegółowe informacje.
Głębokość stosu wywołań - błąd CallDepthExceeded
Programy Solana są ograniczone do szybkiego działania, a aby to umożliwić, stos wywołań programu jest ograniczony do maksymalnej głębokości 64 ramek.
Kiedy program przekroczy dozwolony limit głębokości stosu wywołań, otrzyma błąd
CallDepthExceeded
.
Głębokość wywołań CPI - błąd CallDepth
Wywołania międzyprogramowe (Cross-program invocations) pozwalają programom
bezpośrednio wywoływać inne programy, ale głębokość jest obecnie ograniczona do
4
.
Kiedy program przekroczy dozwoloną
głębokość wywołań międzyprogramowych, otrzyma błąd
CallDepth
.
Obsługa typów zmiennoprzecinkowych w Rust
Programy obsługują ograniczony podzbiór operacji zmiennoprzecinkowych w Rust. Jeśli program spróbuje użyć operacji zmiennoprzecinkowej, która nie jest obsługiwana, środowisko wykonawcze zgłosi błąd nierozwiązanego symbolu.
Operacje zmiennoprzecinkowe są wykonywane za pomocą bibliotek programowych, konkretnie wbudowanych funkcji zmiennoprzecinkowych LLVM. Ze względu na emulację programową zużywają one więcej jednostek obliczeniowych niż operacje na liczbach całkowitych. Ogólnie zaleca się stosowanie operacji na liczbach stałoprzecinkowych, jeśli to możliwe.
Testy matematyki w Solana Program Library raportują wydajność niektórych operacji matematycznych. Aby uruchomić test, zsynchronizuj repozytorium i uruchom:
cargo test-sbf -- --nocapture --test-threads=1
Najnowsze wyniki pokazują, że operacje zmiennoprzecinkowe wymagają więcej instrukcji w porównaniu do ich odpowiedników na liczbach całkowitych. Implementacje stałoprzecinkowe mogą się różnić, ale również będą mniej wymagające niż odpowiedniki zmiennoprzecinkowe:
u64 f32Multiply 8 176Divide 9 219
Statyczne dane zapisywalne
Obiekty współdzielone programów nie obsługują współdzielonych danych zapisywalnych. Programy są współdzielone między wieloma równoległymi wykonaniami, używając tych samych współdzielonych danych i kodu tylko do odczytu. Oznacza to, że deweloperzy nie powinni uwzględniać żadnych statycznych zmiennych zapisywalnych ani globalnych w programach. W przyszłości może zostać dodany mechanizm kopiowania przy zapisie (copy-on-write), aby obsługiwać dane zapisywalne.
Dzielenie ze znakiem
Zestaw instrukcji SBF nie obsługuje dzielenia ze znakiem.
Is this page helpful?