Skip to content

Commit 6374c43

Browse files
committed
Add BackendApi::addr_validate
1 parent 76815ba commit 6374c43

File tree

4 files changed

+38
-21
lines changed

4 files changed

+38
-21
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ and this project adheres to
8080
queriers directly. ([#1977])
8181
- cosmwasm-vm: Rename `BackendApi::canonical_address`/`::human_address` to
8282
`::addr_canonicalize`/`::addr_humanize` for consistency.
83+
- cosmwasm-vm: Add `BackendApi::addr_validate` to avoid having to do two calls
84+
from Rust into Go.
8385

8486
[#1874]: https://github.com/CosmWasm/cosmwasm/pull/1874
8587
[#1876]: https://github.com/CosmWasm/cosmwasm/pull/1876

packages/vm/src/backend.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ pub trait Storage {
166166
/// These should all be pure (stateless) functions. If you need state, you probably want
167167
/// to use the Querier.
168168
pub trait BackendApi: Copy + Clone + Send {
169+
fn addr_validate(&self, input: &str) -> BackendResult<()>;
169170
fn addr_canonicalize(&self, human: &str) -> BackendResult<Vec<u8>>;
170171
fn addr_humanize(&self, canonical: &[u8]) -> BackendResult<String>;
171172
}

packages/vm/src/imports.rs

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -162,31 +162,15 @@ pub fn do_addr_validate<A: BackendApi + 'static, S: Storage + 'static, Q: Querie
162162
Err(_) => return write_to_contract(data, &mut store, b"Input is not valid UTF-8"),
163163
};
164164

165-
let (result, gas_info) = data.api.addr_canonicalize(&source_string);
166-
process_gas_info(data, &mut store, gas_info)?;
167-
let canonical = match result {
168-
Ok(data) => data,
169-
Err(BackendError::UserErr { msg, .. }) => {
170-
return write_to_contract(data, &mut store, msg.as_bytes())
171-
}
172-
Err(err) => return Err(VmError::from(err)),
173-
};
174-
175-
let (result, gas_info) = data.api.addr_humanize(&canonical);
165+
let (result, gas_info) = data.api.addr_validate(&source_string);
176166
process_gas_info(data, &mut store, gas_info)?;
177-
let normalized = match result {
178-
Ok(addr) => addr,
167+
match result {
168+
Ok(()) => Ok(0),
179169
Err(BackendError::UserErr { msg, .. }) => {
180-
return write_to_contract(data, &mut store, msg.as_bytes())
170+
write_to_contract(data, &mut store, msg.as_bytes())
181171
}
182-
Err(err) => return Err(VmError::from(err)),
183-
};
184-
185-
if normalized != source_string {
186-
return write_to_contract(data, &mut store, b"Address is not normalized");
172+
Err(err) => Err(VmError::from(err)),
187173
}
188-
189-
Ok(0)
190174
}
191175

192176
pub fn do_addr_canonicalize<A: BackendApi + 'static, S: Storage + 'static, Q: Querier + 'static>(

packages/vm/src/testing/mock.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,36 @@ impl Default for MockApi {
125125
}
126126

127127
impl BackendApi for MockApi {
128+
fn addr_validate(&self, input: &str) -> BackendResult<()> {
129+
let mut gas = GasInfo {
130+
cost: 0,
131+
externally_used: 0,
132+
};
133+
134+
let (result, gas_info) = self.addr_canonicalize(input);
135+
gas += gas_info;
136+
let canonical = match result {
137+
Ok(canonical) => canonical,
138+
Err(err) => return (Err(err), gas),
139+
};
140+
141+
let (result, gas_info) = self.addr_humanize(&canonical);
142+
gas += gas_info;
143+
let normalized = match result {
144+
Ok(norm) => norm,
145+
Err(err) => return (Err(err), gas),
146+
};
147+
if input != normalized.as_str() {
148+
return (
149+
Err(BackendError::user_err(
150+
"Invalid input: address not normalized",
151+
)),
152+
gas,
153+
);
154+
}
155+
(Ok(()), gas)
156+
}
157+
128158
fn addr_canonicalize(&self, input: &str) -> BackendResult<Vec<u8>> {
129159
let gas_info = GasInfo::with_cost(GAS_COST_CANONICALIZE);
130160

0 commit comments

Comments
 (0)