Skip to content

Commit 34914b1

Browse files
authored
Merge pull request #1986 from CosmWasm/try_br-refactor
Refactor try_br macro
2 parents b94f6f3 + e0d45c8 commit 34914b1

File tree

2 files changed

+36
-32
lines changed

2 files changed

+36
-32
lines changed

packages/vm/src/backend.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -195,18 +195,24 @@ pub trait Querier {
195195
/// must always have gas information attached.
196196
pub type BackendResult<T> = (core::result::Result<T, BackendError>, GasInfo);
197197

198-
/// The equivalent of the `?` operator, but for a [`BackendResult`]
199-
macro_rules! try_br {
200-
($res: expr $(,)?) => {
201-
let (result, gas) = $res;
202-
198+
/// This aims to be similar to the `?` operator, but for a [`BackendResult`].
199+
///
200+
/// The first argument is a result. If it is Ok, return the value.
201+
/// If it is Err, end the current function with a `return BackendResult::Err`.
202+
///
203+
/// The second argument is the gas value that will be used in the error case.
204+
/// It should be the sum of all gas used in the calling function.
205+
macro_rules! unwrap_or_return_with_gas {
206+
($result: expr $(,)?, $gas_total: expr $(,)?) => {{
207+
let result: core::result::Result<_, _> = $result; // just a type check
208+
let gas: GasInfo = $gas_total; // just a type check
203209
match result {
204210
Ok(v) => v,
205211
Err(e) => return (Err(e), gas),
206212
}
207-
};
213+
}};
208214
}
209-
pub(crate) use try_br;
215+
pub(crate) use unwrap_or_return_with_gas;
210216

211217
#[derive(Error, Debug, PartialEq, Eq)]
212218
#[non_exhaustive]

packages/vm/src/testing/mock.rs

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use sha2::{Digest, Sha256};
66

77
use super::querier::MockQuerier;
88
use super::storage::MockStorage;
9-
use crate::backend::try_br;
9+
use crate::backend::unwrap_or_return_with_gas;
1010
use crate::{Backend, BackendApi, BackendError, BackendResult, GasInfo};
1111

1212
pub const MOCK_CONTRACT_ADDR: &str = "cosmwasmcontract"; // TODO: use correct address
@@ -131,19 +131,13 @@ impl BackendApi for MockApi {
131131
externally_used: 0,
132132
};
133133

134-
let (result, gas_info) = self.addr_canonicalize(input);
134+
let (canonicalize_res, gas_info) = self.addr_canonicalize(input);
135135
gas_total += gas_info;
136-
let canonical = match result {
137-
Ok(canonical) => canonical,
138-
Err(err) => return (Err(err), gas_total),
139-
};
136+
let canonical = unwrap_or_return_with_gas!(canonicalize_res, gas_total);
140137

141-
let (result, gas_info) = self.addr_humanize(&canonical);
138+
let (humanize_res, gas_info) = self.addr_humanize(&canonical);
142139
gas_total += gas_info;
143-
let normalized = match result {
144-
Ok(norm) => norm,
145-
Err(err) => return (Err(err), gas_total),
146-
};
140+
let normalized = unwrap_or_return_with_gas!(humanize_res, gas_total);
147141
if input != normalized.as_str() {
148142
return (
149143
Err(BackendError::user_err(
@@ -156,51 +150,55 @@ impl BackendApi for MockApi {
156150
}
157151

158152
fn addr_canonicalize(&self, input: &str) -> BackendResult<Vec<u8>> {
159-
let gas_info = GasInfo::with_cost(GAS_COST_CANONICALIZE);
153+
let gas_total = GasInfo::with_cost(GAS_COST_CANONICALIZE);
160154

161155
// handle error case
162156
let bech32_prefix = match self.0 {
163-
MockApiImpl::Error(e) => return (Err(BackendError::unknown(e)), gas_info),
157+
MockApiImpl::Error(e) => return (Err(BackendError::unknown(e)), gas_total),
164158
MockApiImpl::Bech32 { bech32_prefix } => bech32_prefix,
165159
};
166160

167161
match decode(input) {
168-
Ok((prefix, _, _)) if prefix != bech32_prefix => {
169-
(Err(BackendError::user_err("Wrong bech32 prefix")), gas_info)
170-
}
162+
Ok((prefix, _, _)) if prefix != bech32_prefix => (
163+
Err(BackendError::user_err("Wrong bech32 prefix")),
164+
gas_total,
165+
),
171166
Ok((_, _, Variant::Bech32m)) => (
172167
Err(BackendError::user_err("Wrong bech32 variant")),
173-
gas_info,
168+
gas_total,
174169
),
175170
Err(_) => (
176171
Err(BackendError::user_err("Error decoding bech32")),
177-
gas_info,
172+
gas_total,
178173
),
179174
Ok((_, decoded, Variant::Bech32)) => match Vec::<u8>::from_base32(&decoded) {
180175
Ok(bytes) => {
181-
try_br!((validate_length(&bytes), gas_info));
182-
(Ok(bytes), gas_info)
176+
unwrap_or_return_with_gas!(validate_length(&bytes), gas_total);
177+
(Ok(bytes), gas_total)
183178
}
184-
Err(_) => (Err(BackendError::user_err("Invalid bech32 data")), gas_info),
179+
Err(_) => (
180+
Err(BackendError::user_err("Invalid bech32 data")),
181+
gas_total,
182+
),
185183
},
186184
}
187185
}
188186

189187
fn addr_humanize(&self, canonical: &[u8]) -> BackendResult<String> {
190-
let gas_info = GasInfo::with_cost(GAS_COST_HUMANIZE);
188+
let gas_total = GasInfo::with_cost(GAS_COST_HUMANIZE);
191189

192190
// handle error case
193191
let bech32_prefix = match self.0 {
194-
MockApiImpl::Error(e) => return (Err(BackendError::unknown(e)), gas_info),
192+
MockApiImpl::Error(e) => return (Err(BackendError::unknown(e)), gas_total),
195193
MockApiImpl::Bech32 { bech32_prefix } => bech32_prefix,
196194
};
197195

198-
try_br!((validate_length(canonical), gas_info));
196+
unwrap_or_return_with_gas!(validate_length(canonical), gas_total);
199197

200198
let result = encode(bech32_prefix, canonical.to_base32(), Variant::Bech32)
201199
.map_err(|_| BackendError::user_err("Invalid bech32 prefix"));
202200

203-
(result, gas_info)
201+
(result, gas_total)
204202
}
205203
}
206204

0 commit comments

Comments
 (0)