Skip to content

Commit

Permalink
Merge pull request #56 from OffchainLabs/better-docs
Browse files Browse the repository at this point in the history
Better doc links
  • Loading branch information
rachel-bousfield authored Sep 7, 2023
2 parents 749a709 + 42102bd commit af88573
Show file tree
Hide file tree
Showing 12 changed files with 57 additions and 42 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ members = ["stylus-sdk", "stylus-proc"]
resolver = "2"

[workspace.package]
version = "0.2.1"
version = "0.2.2"
edition = "2021"
authors = ["Offchain Labs"]
license = "MIT OR Apache-2.0"
Expand Down
1 change: 1 addition & 0 deletions stylus-sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,4 @@ default = ["storage-cache"]
export-abi = ["debug", "regex", "stylus-proc/export-abi"]
debug = []
storage-cache = ["fnv"]
docs = []
4 changes: 3 additions & 1 deletion stylus-sdk/src/abi/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ use regex::Regex;

/// Trait for storage types so that users can print a Solidity interface to the console.
/// This is auto-derived via the [`external`] marco when the `export-abi` feature is enabled.
///
/// [`external`]: stylus-proc::external
pub trait GenerateAbi {
/// The interface's name.
const NAME: &'static str;

/// How to format the ABI. Analogous to [`Display`].
/// How to format the ABI. Analogous to [`Display`](std::fmt::Display).
fn fmt_abi(f: &mut fmt::Formatter<'_>) -> fmt::Result;
}

Expand Down
6 changes: 4 additions & 2 deletions stylus-sdk/src/call/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,17 @@ pub trait StaticCallContext: CallContext {}
///
/// # Safety
///
/// The type must contain a [`TopLevelStorage`] to prevent aliasing in cases of reentrancy.
/// The type must contain a [`TopLevelStorage`][TLS] to prevent aliasing in cases of reentrancy.
///
/// [TLS]: crate::storage::TopLevelStorage
pub unsafe trait MutatingCallContext: CallContext {
/// Amount of ETH in wei to give the other contract.
fn value(&self) -> U256;
}

/// Trait for calling the `write` methods of other contracts.
/// Users should rarely implement this trait outside of proc macros.
/// Note: any implementations of this must return zero for [`MutableCallContext::value`].
/// Note: any implementations of this must return zero for [`MutatingCallContext::value`].
pub trait NonPayableCallContext: MutatingCallContext {}

impl CallContext for () {
Expand Down
4 changes: 2 additions & 2 deletions stylus-sdk/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
use alloy_primitives::{Address, U256};

/// Reads the invocation's calldata.
/// The [`derive(Entrypoint)`] and [`entrypoint`] macros use this under the hood.
/// The [`entrypoint`](macro@stylus_proc::entrypoint) macro uses this under the hood.
pub fn args(len: usize) -> Vec<u8> {
let mut input = Vec::with_capacity(len);
unsafe {
Expand All @@ -19,7 +19,7 @@ pub fn args(len: usize) -> Vec<u8> {
}

/// Writes the contract's return data.
/// The [`derive(Entrypoint)`] and [`entrypoint!`] macros use this under the hood.
/// The [`entrypoint`](macro@stylus_proc::entrypoint) macro uses this under the hood.
pub fn output(data: &[u8]) {
unsafe {
hostio::write_result(data.as_ptr(), data.len());
Expand Down
2 changes: 1 addition & 1 deletion stylus-sdk/src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ fn emit_log(bytes: &[u8], topics: usize) {
}

/// Emits an EVM log from its raw topics and data.
/// Most users should prefer the alloy-typed [`emit_log`].
/// Most users should prefer the alloy-typed [`raw_log`].
pub fn raw_log(topics: &[B256], data: &[u8]) -> Result<(), &'static str> {
if topics.len() > 4 {
return Err("too many topics");
Expand Down
6 changes: 4 additions & 2 deletions stylus-sdk/src/storage/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ use lazy_static::lazy_static;
///
/// This is intended for most use cases. However, one may opt-out
/// of this behavior by turning off default features and not enabling
/// the `storage-cache` feature. Doing so will provide the [`EagerStorage`] type
/// for managing state in the absence of caching.
/// the `storage-cache` feature. Doing so will provide the [`EagerStorage`]
/// type for managing state in the absence of caching.
///
/// [`EagerStorage`]: super::EagerStorage
pub struct StorageCache(HashMap<U256, StorageWord>);

/// Represents the EVM word at a given key.
Expand Down
2 changes: 2 additions & 0 deletions stylus-sdk/src/storage/eager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ use alloy_primitives::{B256, U256};
/// `storage-cache` feature flag, which will provide the [`StorageCache`] type.
///
/// Note that individual primitive types may still include efficient caching.
///
/// [`StorageCache`]: super::StorageCache
pub struct EagerStorage;

impl GlobalStorage for EagerStorage {
Expand Down
48 changes: 24 additions & 24 deletions stylus-sdk/src/storage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use core::{cell::OnceCell, marker::PhantomData, ops::Deref};

pub use array::StorageArray;
pub use bytes::{StorageBytes, StorageString};
pub use map::StorageMap;
pub use map::{StorageKey, StorageMap};
pub use traits::{
Erase, GlobalStorage, SimpleStorageType, StorageGuard, StorageGuardMut, StorageType,
TopLevelStorage,
Expand All @@ -18,7 +18,7 @@ pub use vec::StorageVec;
#[cfg(feature = "storage-cache")]
pub use cache::StorageCache;

#[cfg(not(feature = "storage-cache"))]
#[cfg(any(not(feature = "storage-cache"), feature = "docs"))]
pub use eager::EagerStorage;

mod array;
Expand All @@ -30,7 +30,7 @@ mod vec;
#[cfg(feature = "storage-cache")]
mod cache;

#[cfg(not(feature = "storage-cache"))]
#[cfg(any(not(feature = "storage-cache"), feature = "docs"))]
mod eager;

#[cfg(feature = "storage-cache")]
Expand Down Expand Up @@ -69,26 +69,25 @@ fn overwrite_cell<T>(cell: &mut OnceCell<T>, value: T) {
macro_rules! alias_ints {
($($name:ident, $signed_name:ident, $bits:expr, $limbs:expr;)*) => {
$(
#[doc = concat!("Accessor for a storage-backed [`U", stringify!($bits), "`].")]
#[doc = concat!("Accessor for a storage-backed [`alloy_primitives::aliases::U", stringify!($bits), "`].")]
pub type $name = StorageUint<$bits, $limbs>;

#[doc = concat!("Accessor for a storage-backed [`I", stringify!($bits), "`].")]
#[doc = concat!("Accessor for a storage-backed [`alloy_primitives::aliases::I", stringify!($bits), "`].")]
pub type $signed_name = StorageSigned<$bits, $limbs>;
)*
};
}

macro_rules! alias_bytes {
($($name:ident, $bytes:expr;)*) => {
($($name:ident, $bits:expr, $bytes:expr;)*) => {
$(
#[doc = concat!("Accessor for a storage-backed [`B", stringify!($bytes), "`].")]
#[doc = concat!("Accessor for a storage-backed [`alloy_primitives::aliases::B", stringify!($bits), "`].")]
pub type $name = StorageFixedBytes<$bytes>;
)*
};
}

alias_ints! {
StorageU0, StorageI0, 0, 0;
StorageU1, StorageI1, 1, 1;
StorageU8, StorageI8, 8, 1;
StorageU16, StorageI16, 16, 1;
Expand All @@ -101,20 +100,20 @@ alias_ints! {
}

alias_bytes! {
StorageB0, 0;
StorageB8, 1;
StorageB16, 2;
StorageB32, 4;
StorageB64, 8;
StorageB96, 12;
StorageB128, 16;
StorageB160, 20;
StorageB192, 24;
StorageB224, 28;
StorageB256, 32;
}

/// Accessor for a storage-backed [`Uint`].
StorageB8, 8, 1;
StorageB16, 16, 2;
StorageB32, 32, 4;
StorageB64, 64, 8;
StorageB96, 96, 12;
StorageB128, 128, 16;
StorageB160, 160, 20;
StorageB192, 192, 24;
StorageB224, 224, 28;
StorageB256, 256, 32;
}

/// Accessor for a storage-backed [`alloy_primitives::Uint`].
///
/// Note: in the future `L` won't be needed.
// TODO: drop L after SupportedInt provides LIMBS (waiting for clarity reasons)
#[derive(Debug)]
Expand All @@ -125,12 +124,12 @@ pub struct StorageUint<const B: usize, const L: usize> {
}

impl<const B: usize, const L: usize> StorageUint<B, L> {
/// Gets the underlying [`Uint`] in persistent storage.
/// Gets the underlying [`alloy_primitives::Uint`] in persistent storage.
pub fn get(&self) -> Uint<B, L> {
**self
}

/// Sets the underlying [`Uint`] in persistent storage.
/// Sets the underlying [`alloy_primitives::Uint`] in persistent storage.
pub fn set(&mut self, value: Uint<B, L>) {
overwrite_cell(&mut self.cached, value);
unsafe { Storage::set_uint(self.slot, self.offset.into(), value) };
Expand Down Expand Up @@ -189,6 +188,7 @@ impl<const B: usize, const L: usize> From<StorageUint<B, L>> for Uint<B, L> {
}

/// Accessor for a storage-backed [`Signed`].
///
/// Note: in the future `L` won't be needed.
// TODO: drop L after SupportedInt provides LIMBS (waiting for clarity reasons)
#[derive(Debug)]
Expand Down
14 changes: 8 additions & 6 deletions stylus-sdk/src/storage/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use derivative::Derivative;
/// Users can implement this trait to add novel data structures to their contract definitions.
/// The Stylus SDK by default provides only solidity types, which are represented [`the same way`].
///
/// [`the same way`]: https://docs.soliditylang.org/en/v0.8.15/internals/layout_in_storage.html
/// [`the same way`]: https://docs.soliditylang.org/en/latest/internals/layout_in_storage.html
pub trait StorageType: Sized {
/// For primative types, this is the type being stored.
/// For collections, this is the [`StorageType`] being collected.
Expand All @@ -31,10 +31,11 @@ pub trait StorageType: Sized {
/// set this to 32 and return the full size in [`StorageType::new`].
///
/// For implementing collections, see how Solidity slots are assigned for [`Arrays and Maps`] and their
/// Stylus equivalents [`StorageVec`] and [`StorageMap`].
/// For multi-word, but still-fixed-size types, see the implementations for structs and [`StorageArray`].
/// Stylus equivalents [`StorageVec`](super::StorageVec) and [`StorageMap`](super::StorageMap).
/// For multi-word, but still fixed-size types, see the implementations for structs
/// and [`StorageArray`](super::StorageArray).
///
/// [`Arrays and Maps`]: https://docs.soliditylang.org/en/v0.8.15/internals/layout_in_storage.html#mappings-and-dynamic-arrays
/// [`Arrays and Maps`]: https://docs.soliditylang.org/en/latest/internals/layout_in_storage.html#mappings-and-dynamic-arrays
const SLOT_BYTES: usize = 32;

/// The number of words this type must fill. For primitives this is always 0.
Expand Down Expand Up @@ -66,7 +67,7 @@ pub trait StorageType: Sized {
}

/// Trait for accessors that can be used to completely erase their underlying value.
/// Note that some collections, like [`StorageMap`], don't implement this trait.
/// Note that some collections, like [`StorageMap`](super::StorageMap), don't implement this trait.
pub trait Erase: StorageType {
/// Erase the value from persistent storage.
fn erase(&mut self);
Expand Down Expand Up @@ -174,7 +175,8 @@ impl<'a, T: 'a> DerefMut for StorageGuardMut<'a, T> {
}

/// Trait for managing access to persistent storage.
/// Notable implementations include the [`StorageCache`] and [`EagerStorage`] types.
/// Notable implementations include the [`StorageCache`](super::StorageCache)
/// and [`EagerStorage`](super::EagerStorage) types.
pub trait GlobalStorage {
/// Retrieves `N ≤ 32` bytes from persistent storage, performing [`SLOAD`]'s only as needed.
/// The bytes are read from slot `key`, starting `offset` bytes from the left.
Expand Down
6 changes: 5 additions & 1 deletion stylus-sdk/src/storage/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ impl<S: StorageType> StorageVec<S> {
}

/// Gets an accessor to the element at a given index, if it exists.
///
/// Note: the accessor is protected by a [`StorageGuard`], which restricts
/// its lifetime to that of `&self`.
pub fn getter(&self, index: impl TryInto<usize>) -> Option<StorageGuard<S>> {
Expand All @@ -69,6 +70,7 @@ impl<S: StorageType> StorageVec<S> {
}

/// Gets a mutable accessor to the element at a given index, if it exists.
///
/// Note: the accessor is protected by a [`StorageGuardMut`], which restricts
/// its lifetime to that of `&mut self`.
pub fn setter(&mut self, index: impl TryInto<usize>) -> Option<StorageGuardMut<S>> {
Expand Down Expand Up @@ -112,7 +114,7 @@ impl<S: StorageType> StorageVec<S> {
Some(store.load_mut())
}

/// Like [`std::Vec::push`], but returns a mutable accessor to the new slot.
/// Like [`std::vec::Vec::push`], but returns a mutable accessor to the new slot.
/// This enables pushing elements without constructing them first.
///
/// # Example
Expand Down Expand Up @@ -151,6 +153,7 @@ impl<S: StorageType> StorageVec<S> {
}

/// Shortens the vector, keeping the first `len` elements.
///
/// Note: this method does not erase any underlying storage.
pub fn truncate(&mut self, len: usize) {
if len < self.len() {
Expand Down Expand Up @@ -190,6 +193,7 @@ impl<'a, S: SimpleStorageType<'a>> StorageVec<S> {
}

/// Removes and returns the last element of the vector, if it exists.
///
/// Note: the underlying storage slot is erased when all elements in a word are freed.
pub fn pop(&mut self) -> Option<S::Wraps<'a>> {
let store = unsafe { self.shrink()?.into_raw() };
Expand Down

0 comments on commit af88573

Please sign in to comment.