Skip to content

Commit 33bee8a

Browse files
committed
refactor(axelar-gateway): use contractstorage
1 parent bdc02e6 commit 33bee8a

File tree

6 files changed

+133
-138
lines changed

6 files changed

+133
-138
lines changed

contracts/stellar-axelar-gateway/src/auth.rs

Lines changed: 20 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use stellar_axelar_std::events::Event;
44

55
use crate::error::ContractError;
66
use crate::event::SignersRotatedEvent;
7-
use crate::storage_types::DataKey;
7+
use crate::storage;
88
use crate::types::{Proof, ProofSignature, ProofSigner, WeightedSigner, WeightedSigners};
99

1010
pub fn initialize_auth(
@@ -14,20 +14,10 @@ pub fn initialize_auth(
1414
previous_signer_retention: u64,
1515
initial_signers: Vec<WeightedSigners>,
1616
) -> Result<(), ContractError> {
17-
env.storage().instance().set(&DataKey::Epoch, &0_u64);
18-
19-
env.storage().instance().set(
20-
&DataKey::PreviousSignerRetention,
21-
&previous_signer_retention,
22-
);
23-
24-
env.storage()
25-
.instance()
26-
.set(&DataKey::DomainSeparator, &domain_separator);
27-
28-
env.storage()
29-
.instance()
30-
.set(&DataKey::MinimumRotationDelay, &minimum_rotation_delay);
17+
storage::set_epoch(&env, &0_u64);
18+
storage::set_previous_signer_retention(&env, &previous_signer_retention);
19+
storage::set_domain_separator(&env, &domain_separator);
20+
storage::set_minimum_rotation_delay(&env, &minimum_rotation_delay);
3121

3222
ensure!(!initial_signers.is_empty(), ContractError::EmptySigners);
3323

@@ -38,27 +28,6 @@ pub fn initialize_auth(
3828
Ok(())
3929
}
4030

41-
pub fn domain_separator(env: &Env) -> BytesN<32> {
42-
env.storage()
43-
.instance()
44-
.get(&DataKey::DomainSeparator)
45-
.expect("domain_separator not found")
46-
}
47-
48-
pub fn minimum_rotation_delay(env: &Env) -> u64 {
49-
env.storage()
50-
.instance()
51-
.get(&DataKey::MinimumRotationDelay)
52-
.expect("minimum_rotation_delay not found")
53-
}
54-
55-
pub fn previous_signers_retention(env: &Env) -> u64 {
56-
env.storage()
57-
.instance()
58-
.get(&DataKey::PreviousSignerRetention)
59-
.expect("previous_signers_retention not found")
60-
}
61-
6231
pub fn validate_proof(
6332
env: &Env,
6433
data_hash: &BytesN<32>,
@@ -68,14 +37,15 @@ pub fn validate_proof(
6837

6938
let signers_hash = signers_set.hash(env);
7039

71-
let signers_epoch = epoch_by_signers_hash(env, signers_hash.clone())?;
40+
let signers_epoch = storage::try_epoch_by_signers_hash(env, signers_hash.clone())
41+
.ok_or(ContractError::InvalidSignersHash)?;
7242

73-
let current_epoch = epoch(env);
43+
let current_epoch = storage::epoch(env);
7444

7545
let is_latest_signers: bool = signers_epoch == current_epoch;
7646

7747
ensure!(
78-
current_epoch - signers_epoch <= previous_signers_retention(env),
48+
current_epoch - signers_epoch <= storage::previous_signer_retention(env),
7949
ContractError::OutdatedSigners
8050
);
8151

@@ -100,23 +70,20 @@ pub fn rotate_signers(
10070

10171
let new_signers_hash = new_signers.hash(env);
10272

103-
let new_epoch: u64 = epoch(env) + 1;
73+
let new_epoch: u64 = storage::epoch(env) + 1;
10474

105-
env.storage().instance().set(&DataKey::Epoch, &new_epoch);
75+
storage::set_epoch(env, &new_epoch);
10676

107-
env.storage()
108-
.persistent()
109-
.set(&DataKey::SignersHashByEpoch(new_epoch), &new_signers_hash);
77+
storage::set_signers_hash_by_epoch(env, new_epoch, &new_signers_hash);
11078

11179
ensure!(
112-
epoch_by_signers_hash(env, new_signers_hash.clone()).is_err(),
80+
storage::try_epoch_by_signers_hash(env, new_signers_hash.clone())
81+
.ok_or(ContractError::InvalidSignersHash)
82+
.is_err(),
11383
ContractError::DuplicateSigners
11484
);
11585

116-
env.storage().persistent().set(
117-
&DataKey::EpochBySignersHash(new_signers_hash.clone()),
118-
&new_epoch,
119-
);
86+
storage::set_epoch_by_signers_hash(env, new_signers_hash.clone(), &new_epoch);
12087

12188
SignersRotatedEvent {
12289
epoch: new_epoch,
@@ -128,54 +95,26 @@ pub fn rotate_signers(
12895
Ok(())
12996
}
13097

131-
pub fn epoch(env: &Env) -> u64 {
132-
env.storage()
133-
.instance()
134-
.get(&DataKey::Epoch)
135-
.expect("epoch not found")
136-
}
137-
138-
pub fn epoch_by_signers_hash(env: &Env, signers_hash: BytesN<32>) -> Result<u64, ContractError> {
139-
env.storage()
140-
.persistent()
141-
.get(&DataKey::EpochBySignersHash(signers_hash))
142-
.ok_or(ContractError::InvalidSignersHash)
143-
}
144-
145-
pub fn signers_hash_by_epoch(env: &Env, epoch: u64) -> Result<BytesN<32>, ContractError> {
146-
env.storage()
147-
.persistent()
148-
.get(&DataKey::SignersHashByEpoch(epoch))
149-
.ok_or(ContractError::InvalidEpoch)
150-
}
151-
15298
fn message_hash_to_sign(env: &Env, signers_hash: BytesN<32>, data_hash: &BytesN<32>) -> BytesN<32> {
153-
let mut msg: Bytes = domain_separator(env).into();
99+
let mut msg: Bytes = storage::domain_separator(env).into();
154100
msg.extend_from_array(&signers_hash.to_array());
155101
msg.extend_from_array(&data_hash.to_array());
156102

157103
env.crypto().keccak256(&msg).into()
158104
}
159105

160106
fn update_rotation_timestamp(env: &Env, enforce_rotation_delay: bool) -> Result<(), ContractError> {
161-
let last_rotation_timestamp: u64 = env
162-
.storage()
163-
.instance()
164-
.get(&DataKey::LastRotationTimestamp)
165-
.unwrap_or(0);
166-
167107
let current_timestamp = env.ledger().timestamp();
168108

169109
if enforce_rotation_delay {
170110
ensure!(
171-
current_timestamp - last_rotation_timestamp >= minimum_rotation_delay(env),
111+
current_timestamp - storage::last_rotation_timestamp(env)
112+
>= storage::minimum_rotation_delay(env),
172113
ContractError::InsufficientRotationDelay
173114
);
174115
}
175116

176-
env.storage()
177-
.instance()
178-
.set(&DataKey::LastRotationTimestamp, &current_timestamp);
117+
storage::set_last_rotation_timestamp(env, &current_timestamp);
179118

180119
Ok(())
181120
}

contracts/stellar-axelar-gateway/src/contract.rs

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ use stellar_axelar_std::{
66
ensure, interfaces, when_not_paused, Operatable, Ownable, Pausable, Upgradable,
77
};
88

9-
use crate::auth;
109
use crate::error::ContractError;
1110
use crate::event::{ContractCalledEvent, MessageApprovedEvent, MessageExecutedEvent};
1211
use crate::interface::AxelarGatewayInterface;
1312
use crate::messaging_interface::AxelarGatewayMessagingInterface;
14-
use crate::storage_types::{DataKey, MessageApprovalKey, MessageApprovalValue};
13+
use crate::storage::{MessageApprovalKey, MessageApprovalValue};
1514
use crate::types::{CommandType, Message, Proof, WeightedSigners};
15+
use crate::{auth, storage};
1616

1717
#[contract]
1818
#[derive(Operatable, Ownable, Pausable, Upgradable)]
@@ -110,7 +110,8 @@ impl AxelarGatewayMessagingInterface for AxelarGateway {
110110
source_chain: source_chain.clone(),
111111
message_id: message_id.clone(),
112112
};
113-
let message_approval = Self::message_approval_by_key(&env, key.clone());
113+
let message_approval = storage::try_message_approval(&env, key.clone())
114+
.unwrap_or(MessageApprovalValue::NotApproved);
114115
let message = Message {
115116
source_chain,
116117
message_id,
@@ -120,10 +121,7 @@ impl AxelarGatewayMessagingInterface for AxelarGateway {
120121
};
121122

122123
if message_approval == Self::message_approval_hash(&env, message.clone()) {
123-
env.storage().persistent().set(
124-
&DataKey::MessageApproval(key),
125-
&MessageApprovalValue::Executed,
126-
);
124+
storage::set_message_approval(&env, key, &MessageApprovalValue::Executed);
127125

128126
MessageExecutedEvent { message }.emit(&env);
129127

@@ -137,15 +135,15 @@ impl AxelarGatewayMessagingInterface for AxelarGateway {
137135
#[contractimpl]
138136
impl AxelarGatewayInterface for AxelarGateway {
139137
fn domain_separator(env: &Env) -> BytesN<32> {
140-
auth::domain_separator(env)
138+
storage::domain_separator(env)
141139
}
142140

143141
fn minimum_rotation_delay(env: &Env) -> u64 {
144-
auth::minimum_rotation_delay(env)
142+
storage::minimum_rotation_delay(env)
145143
}
146144

147145
fn previous_signers_retention(env: &Env) -> u64 {
148-
auth::previous_signers_retention(env)
146+
storage::previous_signer_retention(env)
149147
}
150148

151149
#[when_not_paused]
@@ -170,13 +168,15 @@ impl AxelarGatewayInterface for AxelarGateway {
170168
};
171169

172170
// Prevent replay if message is already approved/executed
173-
let message_approval = Self::message_approval_by_key(env, key.clone());
171+
let message_approval = storage::try_message_approval(env, key.clone())
172+
.unwrap_or(MessageApprovalValue::NotApproved);
174173
if message_approval != MessageApprovalValue::NotApproved {
175174
continue;
176175
}
177176

178-
env.storage().persistent().set(
179-
&DataKey::MessageApproval(key),
177+
storage::set_message_approval(
178+
env,
179+
key,
180180
&Self::message_approval_hash(env, message.clone()),
181181
);
182182

@@ -214,15 +214,16 @@ impl AxelarGatewayInterface for AxelarGateway {
214214
}
215215

216216
fn epoch(env: &Env) -> u64 {
217-
auth::epoch(env)
217+
storage::epoch(env)
218218
}
219219

220220
fn epoch_by_signers_hash(env: &Env, signers_hash: BytesN<32>) -> Result<u64, ContractError> {
221-
auth::epoch_by_signers_hash(env, signers_hash)
221+
storage::try_epoch_by_signers_hash(env, signers_hash)
222+
.ok_or(ContractError::InvalidSignersHash)
222223
}
223224

224225
fn signers_hash_by_epoch(env: &Env, epoch: u64) -> Result<BytesN<32>, ContractError> {
225-
auth::signers_hash_by_epoch(env, epoch)
226+
storage::try_signers_hash_by_epoch(env, epoch).ok_or(ContractError::InvalidEpoch)
226227
}
227228

228229
fn validate_proof(
@@ -246,15 +247,7 @@ impl AxelarGateway {
246247
message_id,
247248
};
248249

249-
Self::message_approval_by_key(env, key)
250-
}
251-
252-
/// Get the message approval value by key, defaulting to `MessageNotApproved`
253-
fn message_approval_by_key(env: &Env, key: MessageApprovalKey) -> MessageApprovalValue {
254-
env.storage()
255-
.persistent()
256-
.get(&DataKey::MessageApproval(key))
257-
.unwrap_or(MessageApprovalValue::NotApproved)
250+
storage::try_message_approval(env, key).unwrap_or(MessageApprovalValue::NotApproved)
258251
}
259252

260253
fn message_approval_hash(env: &Env, message: Message) -> MessageApprovalValue {

contracts/stellar-axelar-gateway/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ cfg_if::cfg_if! {
2828
} else {
2929
mod auth;
3030
pub mod event;
31-
mod storage_types;
31+
mod storage;
3232
mod contract;
3333

3434
pub use contract::{AxelarGateway, AxelarGatewayClient};
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
use soroban_sdk::{contracttype, BytesN, String};
2+
use stellar_axelar_std::contractstorage;
3+
4+
#[contracttype]
5+
#[derive(Clone, Debug)]
6+
pub struct MessageApprovalKey {
7+
pub source_chain: String,
8+
pub message_id: String,
9+
}
10+
11+
#[contracttype]
12+
#[derive(Clone, Debug, Eq, PartialEq)]
13+
pub enum MessageApprovalValue {
14+
NotApproved,
15+
Approved(BytesN<32>),
16+
Executed,
17+
}
18+
19+
#[contractstorage]
20+
#[derive(Clone, Debug)]
21+
pub enum DataKey {
22+
/// Gateway
23+
#[persistent]
24+
#[value(MessageApprovalValue)]
25+
MessageApproval {
26+
message_approval_key: MessageApprovalKey,
27+
},
28+
29+
/// Auth Module
30+
#[instance]
31+
#[value(u64)]
32+
PreviousSignerRetention,
33+
34+
#[instance]
35+
#[value(BytesN<32>)]
36+
DomainSeparator,
37+
38+
#[instance]
39+
#[value(u64)]
40+
MinimumRotationDelay,
41+
42+
#[instance]
43+
#[value(u64)]
44+
Epoch,
45+
46+
#[instance]
47+
#[value(u64)]
48+
LastRotationTimestamp,
49+
50+
#[persistent]
51+
#[value(BytesN<32>)]
52+
SignersHashByEpoch { epoch: u64 },
53+
54+
#[persistent]
55+
#[value(u64)]
56+
EpochBySignersHash { signers_hash: BytesN<32> },
57+
}

contracts/stellar-axelar-gateway/src/storage_types.rs

Lines changed: 0 additions & 31 deletions
This file was deleted.

0 commit comments

Comments
 (0)