Skip to content

Commit 1ce8364

Browse files
authored
Merge pull request #2471 from CosmWasm/co/raw-range
Implement `RawRange` query
2 parents e1dfb98 + 499fee0 commit 1ce8364

File tree

17 files changed

+440
-21
lines changed

17 files changed

+440
-21
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ and this project adheres to
3333
- cosmwasm-vm: Add `ibc2_packet_send` entrypoint ([#2477])
3434
- cosmwasm-std: Add Tx hash to TransactionInfo and make it non exhaustive
3535
([#2480])
36+
- cosmwasm-std: Add `WasmQuery::RawRange` query to allow querying raw storage
37+
ranges of different contracts. ([#2471])
3638

3739
## Changed
3840

@@ -130,6 +132,7 @@ and this project adheres to
130132
[#2454]: https://github.com/CosmWasm/cosmwasm/pull/2454
131133
[#2458]: https://github.com/CosmWasm/cosmwasm/pull/2458
132134
[#2467]: https://github.com/CosmWasm/cosmwasm/pull/2467
135+
[#2471]: https://github.com/CosmWasm/cosmwasm/pull/2471
133136
[#2472]: https://github.com/CosmWasm/cosmwasm/pull/2472
134137
[#2473]: https://github.com/CosmWasm/cosmwasm/pull/2473
135138
[#2477]: https://github.com/CosmWasm/cosmwasm/pull/2477

docs/CAPABILITIES-BUILT-IN.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,5 @@ might define others.
3333
`migrate` entrypoint, as well as IBC Fees support with `IbcMsg::PayPacketFee`,
3434
`IbcMsg::PayPacketFeeAsync` and `IbcQuery::FeeEnabledChannel`. Only chains
3535
running CosmWasm `2.2.0` or higher support this.
36+
- `cosmwasm_3_0` enables `WasmQuery::RawRange`. Only chains running CosmWasm
37+
`3.0.0` or higher support this.

packages/go-gen/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ release = false
1010

1111
[dependencies]
1212
cosmwasm-std = { version = "3.0.0-ibc2.0", path = "../std", features = [
13-
"cosmwasm_2_2",
13+
"cosmwasm_3_0",
1414
"staking",
1515
"stargate",
1616
] }

packages/go-gen/src/go.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,16 @@ impl Display for GoField {
5050
self.ty,
5151
self.rust_name
5252
)?;
53-
if let Nullability::OmitEmpty | Nullability::Nullable = self.ty.nullability {
54-
f.write_str(",omitempty")?;
53+
match self.ty.nullability {
54+
Nullability::OmitEmpty => {
55+
f.write_str(",omitempty")?;
56+
}
57+
Nullability::Nullable if !self.ty.is_slice() => {
58+
// if the type is nullable, we need to use a pointer type
59+
// and add `omitempty` to the json tag
60+
f.write_str(",omitempty")?;
61+
}
62+
_ => {}
5563
}
5664
f.write_str("\"`")
5765
}
@@ -100,12 +108,17 @@ impl GoType {
100108
];
101109
BASIC_GO_TYPES.contains(&&*self.name)
102110
}
111+
112+
pub fn is_slice(&self) -> bool {
113+
self.name.starts_with("[]")
114+
}
103115
}
104116

105117
impl Display for GoType {
106118
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
107-
if self.nullability == Nullability::Nullable && !self.is_basic_type() {
119+
if self.nullability == Nullability::Nullable && !self.is_basic_type() && !self.is_slice() {
108120
// if the type is nullable and not a basic type, use a pointer
121+
// slices are already pointers, so we don't need to do anything for them
109122
f.write_char('*')?;
110123
}
111124
f.write_str(&self.name)

packages/go-gen/src/main.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ mod schema;
1111
mod utils;
1212

1313
fn main() -> Result<()> {
14-
let root = cosmwasm_schema::schema_for!(cosmwasm_std::Reply);
14+
let root = cosmwasm_schema::schema_for!(cosmwasm_std::RawRangeResponse);
1515

1616
let code = generate_go(root)?;
1717
println!("{}", code);
@@ -198,6 +198,7 @@ mod tests {
198198

199199
use super::*;
200200

201+
#[track_caller]
201202
fn assert_code_eq(actual: String, expected: &str) {
202203
let actual_no_ws = actual.split_whitespace().collect::<Vec<_>>();
203204
let expected_no_ws = expected.split_whitespace().collect::<Vec<_>>();
@@ -210,6 +211,7 @@ mod tests {
210211
);
211212
}
212213

214+
#[track_caller]
213215
fn assert_code_eq_ignore_docs(actual: String, expected: &str) {
214216
let actual_filtered = actual
215217
.lines()
@@ -251,7 +253,7 @@ mod tests {
251253
Binary []byte `json:"binary"`
252254
Checksum Checksum `json:"checksum"`
253255
HexBinary string `json:"hex_binary"`
254-
NestedBinary Array[*[]byte] `json:"nested_binary"`
256+
NestedBinary Array[[]byte] `json:"nested_binary"`
255257
Uint128 string `json:"uint128"`
256258
}"#,
257259
);
@@ -340,7 +342,7 @@ mod tests {
340342
compare_codes!(cosmwasm_std::SupplyResponse);
341343
compare_codes!(cosmwasm_std::BalanceResponse);
342344
compare_codes!(cosmwasm_std::DenomMetadataResponse);
343-
// compare_codes!(cosmwasm_std::AllDenomMetadataResponse); // uses `[]byte` instead of `*[]byte`
345+
// compare_codes!(cosmwasm_std::AllDenomMetadataResponse); // uses slice instead of `Array` type
344346
// staking
345347
compare_codes!(cosmwasm_std::BondedDenomResponse);
346348
compare_codes!(cosmwasm_std::AllDelegationsResponse);
@@ -355,6 +357,7 @@ mod tests {
355357
// wasm
356358
compare_codes!(cosmwasm_std::ContractInfoResponse);
357359
compare_codes!(cosmwasm_std::CodeInfoResponse);
360+
compare_codes!(cosmwasm_std::RawRangeResponse);
358361
}
359362

360363
#[test]
@@ -475,6 +478,8 @@ mod tests {
475478

476479
#[cw_serde]
477480
struct D {
481+
// this should not get an `omitempty` because that prevents us from distinguishing between
482+
// `None` and `Some(vec![])`
478483
d: Option<Vec<String>>,
479484
nested: Vec<Option<Vec<String>>>,
480485
}
@@ -483,8 +488,8 @@ mod tests {
483488
code,
484489
r#"
485490
type D struct {
486-
D *[]string `json:"d,omitempty"`
487-
Nested Array[*[]string] `json:"nested"`
491+
D []string `json:"d"`
492+
Nested Array[[]string] `json:"nested"`
488493
}"#,
489494
);
490495
}

packages/go-gen/src/schema.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,8 @@ pub fn type_from_instance_type(
212212

213213
// for nullable array item types, we have to use a pointer type, even for basic types,
214214
// so we can pass null as elements
215-
// otherwise they would just be omitted from the array
216-
let maybe_ptr = if item_type.nullability == Nullability::Nullable {
215+
// otherwise they would just be omitted from the array, unless it's a slice itself
216+
let maybe_ptr = if item_type.nullability == Nullability::Nullable && !item_type.is_slice() {
217217
"*"
218218
} else {
219219
""
@@ -246,6 +246,16 @@ pub fn array_item_type(
246246
Some(SingleOrVec::Single(array_validation)) => {
247247
schema_object_type(array_validation.object()?, type_context, additional_structs)
248248
}
249+
Some(SingleOrVec::Vec(v))
250+
if v.len() == 1 || v.len() > 1 && v.windows(2).all(|w| w[0] == w[1]) =>
251+
{
252+
// all items are the same type
253+
schema_object_type(
254+
v.first().unwrap().object()?,
255+
type_context,
256+
additional_structs,
257+
)
258+
}
249259
_ => bail!("array type with non-singular item type is not supported"),
250260
}
251261
}
@@ -288,6 +298,7 @@ pub fn custom_type_of(ty: &str) -> Option<&str> {
288298
"Uint128" => Some("string"),
289299
"Uint256" => Some("string"),
290300
"Uint512" => Some("string"),
301+
"Order" => Some("string"),
291302
"Int64" => Some("Int64"),
292303
"Int128" => Some("string"),
293304
"Int256" => Some("string"),
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
type RawRangeResponse struct {
2+
// The key-value pairs
3+
Data Array[Array[[]byte]] `json:"data"`
4+
// `None` if there are no more key-value pairs within the given key range.
5+
NextKey []byte `json:"next_key"`
6+
}

packages/go-gen/tests/cosmwasm_std__WasmQuery.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,27 @@ type CodeInfoQuery struct {
2222
CodeID uint64 `json:"code_id"`
2323
}
2424

25+
type RawRangeQuery struct {
26+
// The address of the contract to query
27+
ContractAddr string `json:"contract_addr"`
28+
// Exclusive end bound. This is the key after the last key you would like to get data for.
29+
End []byte `json:"end"`
30+
// Maximum number of elements to return.
31+
//
32+
// Make sure to set a reasonable limit to avoid running out of memory or into the deserialization limits of the VM. Also keep in mind that these limitations depend on the full JSON size of the response type.
33+
Limit uint16 `json:"limit"`
34+
// The order in which you want to receive the key-value pairs.
35+
Order string `json:"order"`
36+
// Inclusive start bound. This is the first key you would like to get data for.
37+
//
38+
// If `start` is lexicographically greater than or equal to `end`, an empty range is described, mo matter of the order.
39+
Start []byte `json:"start"`
40+
}
41+
2542
type WasmQuery struct {
2643
Smart *SmartQuery `json:"smart,omitempty"`
2744
Raw *RawQuery `json:"raw,omitempty"`
2845
ContractInfo *ContractInfoQuery `json:"contract_info,omitempty"`
2946
CodeInfo *CodeInfoQuery `json:"code_info,omitempty"`
47+
RawRange *RawRangeQuery `json:"raw_range,omitempty"`
3048
}

packages/std/Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ license = "Apache-2.0"
99
readme = "README.md"
1010

1111
[package.metadata.docs.rs]
12-
features = ["cosmwasm_2_2", "staking", "stargate", "ibc2"]
12+
features = ["cosmwasm_3_0", "staking", "stargate", "ibc2"]
1313

1414
[features]
1515
default = ["exports", "iterator", "std"]
@@ -55,6 +55,9 @@ cosmwasm_2_1 = ["cosmwasm_2_0"]
5555
# This enables functionality that is only available on 2.2 chains.
5656
# It adds `IbcMsg::PayPacketFee` and `IbcMsg::PayPacketFeeAsync`.
5757
cosmwasm_2_2 = ["cosmwasm_2_1"]
58+
# This enables functionality that is only available on 3.0 chains.
59+
# It adds `WasmQuery::RawRange`.
60+
cosmwasm_3_0 = ["cosmwasm_2_2"]
5861

5962
[dependencies]
6063
base64 = "0.22.0"

packages/std/src/exports/exports.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ extern "C" fn requires_cosmwasm_2_1() {}
8282
#[no_mangle]
8383
extern "C" fn requires_cosmwasm_2_2() {}
8484

85+
#[cfg(feature = "cosmwasm_3_0")]
86+
#[no_mangle]
87+
extern "C" fn requires_cosmwasm_3_0() {}
88+
8589
/// interface_version_* exports mark which Wasm VM interface level this contract is compiled for.
8690
/// They can be checked by cosmwasm_vm.
8791
/// Update this whenever the Wasm VM interface breaks.

0 commit comments

Comments
 (0)