Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(axelar-std-derive): add contractstorage attribute macro #216

Merged
merged 33 commits into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
836c8da
feat(axelar-std-derive): add contractstorage attribute macro
nbayindirli Jan 27, 2025
c6de88f
diff lint
nbayindirli Jan 27, 2025
d19ef40
Merge branch 'main' into feature/storage-macro
nbayindirli Jan 28, 2025
03fdb1b
address comments
nbayindirli Jan 28, 2025
194d3ff
address comments
nbayindirli Jan 28, 2025
d83e509
breakup storage_attributes & add transform_variant doc
nbayindirli Jan 29, 2025
b0e388f
make value_type not optional + add fields_data helper
nbayindirli Jan 29, 2025
46bf998
Merge branch 'main' into feature/storage-macro
nbayindirli Jan 29, 2025
6fadf1e
expect lowercase
nbayindirli Jan 29, 2025
1db666a
improve encapsulation with storage_method on StorageType
nbayindirli Jan 29, 2025
0b30445
add ttl method
nbayindirli Jan 29, 2025
6f93793
account for Option<Option<...>> case on getter with ambiguous type
nbayindirli Jan 29, 2025
483e4d6
add deleter_name
nbayindirli Jan 29, 2025
e9d4500
add goldie on storage layout
nbayindirli Jan 29, 2025
4ad84c4
add testing on optional value type
nbayindirli Jan 29, 2025
2f2a4fb
support module-level public functions
nbayindirli Jan 29, 2025
9d035f3
enum private + public access fns
nbayindirli Jan 29, 2025
586ed70
remove println
nbayindirli Jan 29, 2025
0c0b710
remove semi-dupe test
nbayindirli Jan 29, 2025
2d6f63f
lint
nbayindirli Jan 29, 2025
6874515
remove test_storage_schema_stability
nbayindirli Jan 29, 2025
dbd645c
auto generate goldie test on generated code
nbayindirli Jan 29, 2025
b9f3c6a
lint
nbayindirli Jan 29, 2025
8f6416d
lint
nbayindirli Jan 29, 2025
ecfc0a3
remove dead golden file
nbayindirli Jan 29, 2025
3b26a9d
tests
nbayindirli Jan 29, 2025
875b896
tests
nbayindirli Jan 29, 2025
0162d95
tests
nbayindirli Jan 29, 2025
dfa5608
tests
nbayindirli Jan 29, 2025
1c76718
tests
nbayindirli Jan 29, 2025
5f9c95b
lint
nbayindirli Jan 29, 2025
b22d3b2
tests
nbayindirli Jan 29, 2025
c7576ac
address comments
nbayindirli Jan 30, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions Cargo.lock

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

27 changes: 7 additions & 20 deletions contracts/stellar-example/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use stellar_interchain_token_service::InterchainTokenServiceClient;

use crate::event::{ExecutedEvent, TokenReceivedEvent, TokenSentEvent};
use crate::interface::ExampleInterface;
use crate::storage_types::DataKey;
use crate::storage;

#[contract]
#[derive(InterchainTokenExecutable)]
Expand All @@ -34,10 +34,7 @@ impl AxelarExecutableInterface for Example {
type Error = ExampleError;

fn gateway(env: &Env) -> Address {
env.storage()
.instance()
.get(&DataKey::Gateway)
.expect("gateway not found")
storage::gateway(env).expect("gateway not found")
}

fn execute(
Expand Down Expand Up @@ -65,10 +62,7 @@ impl CustomInterchainTokenExecutable for Example {
type Error = ExampleError;

fn __interchain_token_service(env: &Env) -> Address {
env.storage()
.instance()
.get(&DataKey::InterchainTokenService)
.expect("ITS not found")
storage::interchain_token_service(env).expect("interchain token service not found")
}

fn __authorized_execute_with_token(
Expand Down Expand Up @@ -115,23 +109,16 @@ impl Example {
gas_service: Address,
interchain_token_service: Address,
) {
env.storage().instance().set(&DataKey::Gateway, &gateway);
env.storage()
.instance()
.set(&DataKey::GasService, &gas_service);
env.storage()
.instance()
.set(&DataKey::InterchainTokenService, &interchain_token_service);
storage::set_gateway(env, &gateway);
storage::set_gas_service(env, &gas_service);
storage::set_interchain_token_service(env, &interchain_token_service);
}
}

#[contractimpl]
impl ExampleInterface for Example {
fn gas_service(env: &Env) -> Address {
env.storage()
.instance()
.get(&DataKey::GasService)
.expect("gas service not found")
storage::gas_service(env).expect("gas service not found")
}

fn send(
Expand Down
2 changes: 1 addition & 1 deletion contracts/stellar-example/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ extern crate std;
mod contract;
pub mod event;
pub mod interface;
mod storage_types;
mod storage;

pub use contract::{Example, ExampleClient};

Expand Down
18 changes: 18 additions & 0 deletions contracts/stellar-example/src/storage.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use soroban_sdk::{contracttype, Address};
use stellar_axelar_std::contractstorage;

#[contractstorage]
#[derive(Clone, Debug)]
enum DataKey {
#[instance]
#[value(Address)]
Gateway,

#[instance]
#[value(Address)]
GasService,

#[instance]
#[value(Address)]
InterchainTokenService,
}
9 changes: 0 additions & 9 deletions contracts/stellar-example/src/storage_types.rs

This file was deleted.

7 changes: 5 additions & 2 deletions packages/stellar-axelar-std-derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@ proc-macro = true
[features]

[dependencies]
goldie = { workspace = true }
heck = "0.5"
itertools = "0.14"
prettyplease = "0.2"
proc-macro2 = { workspace = true }
quote = "1.0"
syn = { version = "2.0", features = ["full"] }
quote = { version = "1.0", default-features = false }
syn = { version = "2.0", features = ["full", "extra-traits"] }

[dev-dependencies]

Expand Down
56 changes: 56 additions & 0 deletions packages/stellar-axelar-std-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ mod its_executable;
mod operatable;
mod ownable;
mod pausable;
mod storage;
mod upgradable;

use proc_macro::TokenStream;
Expand Down Expand Up @@ -233,3 +234,58 @@ pub fn derive_its_executable(input: TokenStream) -> TokenStream {

its_executable::its_executable(name).into()
}

/// Implements a storage interface for a Stellar contract storage enum.
///
/// The enum variants define contract data keys, with optional named fields as contract data map keys.
/// Each variant requires a `#[value(Type)]` attribute to specify the stored value type.
/// Storage type can be specified with `#[instance]`, `#[persistent]`, or `#[temporary]` attributes (defaults to instance).
///
/// # Example
/// ```rust,ignore
/// # mod test {
/// use soroban_sdk::{contract, contractimpl, contractype, Address, Env, String};
/// use stellar_axelar_std::contractstorage;
///
/// #[contractstorage]
/// #[derive(Clone, Debug)]
/// enum DataKey {
/// #[instance]
/// #[value(Address)]
/// Owner,
///
/// #[persistent]
/// #[value(String)]
/// TokenName { token_id: u32 },
///
/// #[temporary]
/// #[value(u64)]
/// LastUpdate { account: Address },
/// }
///
/// #[contract]
/// pub struct Contract;
///
/// #[contractimpl]
/// impl Contract {
/// pub fn __constructor(
/// env: &Env,
/// token_id: u32,
/// name: String,
/// ) {
/// // Generates: DataKey::set_token_name(env, token_id, &name);
/// DataKey::set_token_name(env, token_id, &name);
/// }
///
/// pub fn token_name(env: &Env, token_id: u32) -> Option<String> {
/// // Generates: DataKey::get_token_name(env, token_id)
/// DataKey::get_token_name(env, token_id)
/// }
/// }
/// # }
/// ```
#[proc_macro_attribute]
pub fn contractstorage(_attr: TokenStream, item: TokenStream) -> TokenStream {
let input = parse_macro_input!(item as DeriveInput);
storage::contractstorage(&input).into()
}
Loading
Loading