Skip to content

Commit 6bdb305

Browse files
committed
Use sections encoding for db_next
1 parent f93200f commit 6bdb305

File tree

3 files changed

+14
-26
lines changed

3 files changed

+14
-26
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ and this project adheres to
4242

4343
- all: The `query` enpoint is now optional. It is still highly recommended to
4444
expose it an almost any use case though.
45+
- all: Change the encoding of the key/value region of the `db_next` import to a
46+
more generic encoding that supports an arbitrary number of sections. This
47+
encoding can then be reused for other multi value regions.
4548
- cosmwasm-std: Remove `from_address` from `BankMsg::Send`, as it always sends
4649
from the contract address, and this is consistent with other `CosmosMsg`
4750
variants.

packages/std/src/imports.rs

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::binary::Binary;
55
use crate::errors::{StdError, StdResult, SystemError};
66
use crate::memory::{alloc, build_region, consume_region, Region};
77
use crate::results::SystemResult;
8+
use crate::sections::decode_sections2;
89
use crate::serde::from_slice;
910
use crate::traits::{Api, Querier, QuerierResult, Storage};
1011
#[cfg(feature = "iterator")]
@@ -120,23 +121,13 @@ impl Iterator for ExternalIterator {
120121
fn next(&mut self) -> Option<Self::Item> {
121122
let next_result = unsafe { db_next(self.iterator_id) };
122123
let kv_region_ptr = next_result as *mut Region;
123-
let mut kv = unsafe { consume_region(kv_region_ptr) };
124-
125-
// The KV region uses the format value || key || keylen, where keylen is a fixed size big endian u32 value
126-
let keylen = u32::from_be_bytes([
127-
kv[kv.len() - 4],
128-
kv[kv.len() - 3],
129-
kv[kv.len() - 2],
130-
kv[kv.len() - 1],
131-
]) as usize;
132-
if keylen == 0 {
133-
return None;
124+
let kv = unsafe { consume_region(kv_region_ptr) };
125+
let (key, value) = decode_sections2(kv);
126+
if key.len() == 0 {
127+
None
128+
} else {
129+
Some((key, value))
134130
}
135-
136-
kv.truncate(kv.len() - 4);
137-
let key = kv.split_off(kv.len() - keylen);
138-
let value = kv;
139-
Some((key, value))
140131
}
141132
}
142133

packages/vm/src/imports.rs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -298,13 +298,7 @@ fn do_next<A: Api, S: Storage, Q: Querier>(
298298
// Empty key will later be treated as _no more element_.
299299
let (key, value) = result?.unwrap_or_else(|| (Vec::<u8>::new(), Vec::<u8>::new()));
300300

301-
// Build value || key || keylen
302-
let keylen_bytes = to_u32(key.len())?.to_be_bytes();
303-
let mut out_data = value;
304-
out_data.reserve(key.len() + 4);
305-
out_data.extend(key);
306-
out_data.extend_from_slice(&keylen_bytes);
307-
301+
let out_data = encode_sections(&[key, value])?;
308302
write_to_contract::<A, S, Q>(env, &out_data)
309303
}
310304

@@ -1158,19 +1152,19 @@ mod tests {
11581152
let kv_region_ptr = do_next::<MA, MS, MQ>(&env, id).unwrap();
11591153
assert_eq!(
11601154
force_read(&env, kv_region_ptr),
1161-
[VALUE1, KEY1, b"\0\0\0\x03"].concat()
1155+
[KEY1, b"\0\0\0\x03", VALUE1, b"\0\0\0\x06"].concat()
11621156
);
11631157

11641158
// Entry 2
11651159
let kv_region_ptr = do_next::<MA, MS, MQ>(&env, id).unwrap();
11661160
assert_eq!(
11671161
force_read(&env, kv_region_ptr),
1168-
[VALUE2, KEY2, b"\0\0\0\x04"].concat()
1162+
[KEY2, b"\0\0\0\x04", VALUE2, b"\0\0\0\x05"].concat()
11691163
);
11701164

11711165
// End
11721166
let kv_region_ptr = do_next::<MA, MS, MQ>(&env, id).unwrap();
1173-
assert_eq!(force_read(&env, kv_region_ptr), b"\0\0\0\0");
1167+
assert_eq!(force_read(&env, kv_region_ptr), b"\0\0\0\0\0\0\0\0");
11741168
// API makes no guarantees for value_ptr in this case
11751169
}
11761170

0 commit comments

Comments
 (0)