Skip to content

Commit eaf14c0

Browse files
authored
Update to upstream rs-matter-stack which features inband persistence (#43)
* Update to upstream rs-matter * Swoitch to the blocking KvBlobStore trait as per upstream * Example with persistent storage * Option to reset the Matter state
1 parent 903f019 commit eaf14c0

20 files changed

Lines changed: 545 additions & 233 deletions

Cargo.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ exclude = ["examples"]
88

99
[patch.crates-io]
1010
#rs-matter = { git = "https://github.com/project-chip/rs-matter" }
11-
rs-matter = { git = "https://github.com/sysgrok/rs-matter", branch = "next" }
11+
#rs-matter = { git = "https://github.com/sysgrok/rs-matter", branch = "next" }
12+
rs-matter = { git = "https://github.com/sysgrok/rs-matter", branch = "inband-persistence" }
1213
#rs-matter = { path = "../../rs-matter/rs-matter" }
13-
rs-matter-stack = { git = "https://github.com/ivmarkov/rs-matter-stack.git", branch = "next" }
14+
#rs-matter-stack = { git = "https://github.com/ivmarkov/rs-matter-stack.git", branch = "next" }
15+
rs-matter-stack = { git = "https://github.com/ivmarkov/rs-matter-stack.git", branch = "inband-persistence" }
1416
#rs-matter-stack = { path = "../../rs-matter-stack" }
1517
openthread = { git = "https://github.com/sysgrok/openthread.git", branch = "next" }
1618
#openthread = { path = "../../../openthread/openthread" }

examples/esp/.cargo/config.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,5 @@ build-std = ["core", "alloc", "panic_abort"]
2020
[env]
2121
DEFMT_LOG="info"
2222
ESP_LOG="info"
23+
# Uncomment and change this if you change the partition table offset (relevant for the light_wifi_persistent example)
24+
#ESP_BOOTLOADER_ESP_IDF_CONFIG_PARTITION_TABLE_OFFSET="0x8000"

examples/esp/Cargo.toml

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ name = "light_wifi"
99
required-features = ["wifi"]
1010
harness = false
1111

12+
[[bin]]
13+
name = "light_wifi_persistent"
14+
required-features = ["wifi"]
15+
harness = false
16+
1217
[[bin]]
1318
name = "light_eth"
1419
required-features = ["wifi"]
@@ -30,9 +35,11 @@ required-features = ["thread"]
3035
harness = false
3136

3237
[patch.crates-io]
33-
rs-matter = { git = "https://github.com/sysgrok/rs-matter", branch = "next" }
38+
#rs-matter = { git = "https://github.com/sysgrok/rs-matter", branch = "next" }
39+
rs-matter = { git = "https://github.com/sysgrok/rs-matter", branch = "inband-persistence" }
3440
#rs-matter = { path = "../../../rs-matter/rs-matter" }
35-
rs-matter-stack = { git = "https://github.com/sysgrok/rs-matter-stack.git", branch = "next" }
41+
#rs-matter-stack = { git = "https://github.com/sysgrok/rs-matter-stack.git", branch = "next" }
42+
rs-matter-stack = { git = "https://github.com/ivmarkov/rs-matter-stack.git", branch = "inband-persistence" }
3643
#rs-matter-stack = { path = "../../../rs-matter-stack" }
3744
openthread = { git = "https://github.com/sysgrok/openthread.git", branch = "next" }
3845
#openthread = { path = "../../../openthread/openthread" }
@@ -42,6 +49,7 @@ esp-hal = { git = "https://github.com/esp-rs/esp-hal", rev = "e156b5453a8adc123b
4249
esp-rtos = { git = "https://github.com/esp-rs/esp-hal", rev = "e156b5453a8adc123b7a8b6aa08e0698ec87dfe8" }
4350
esp-alloc = { git = "https://github.com/esp-rs/esp-hal", rev = "e156b5453a8adc123b7a8b6aa08e0698ec87dfe8" }
4451
esp-println = { git = "https://github.com/esp-rs/esp-hal", rev = "e156b5453a8adc123b7a8b6aa08e0698ec87dfe8" }
52+
esp-storage = { git = "https://github.com/esp-rs/esp-hal", rev = "e156b5453a8adc123b7a8b6aa08e0698ec87dfe8" }
4553
esp-bootloader-esp-idf = { git = "https://github.com/esp-rs/esp-hal", rev = "e156b5453a8adc123b7a8b6aa08e0698ec87dfe8" }
4654
esp-metadata-generated = { git = "https://github.com/esp-rs/esp-hal", rev = "e156b5453a8adc123b7a8b6aa08e0698ec87dfe8" }
4755
#esp-radio = { path = "../../../esp-hal/esp-radio" }
@@ -56,7 +64,7 @@ esp-metadata-generated = { git = "https://github.com/esp-rs/esp-hal", rev = "e15
5664
[profile.dev]
5765
# Rust debug is too slow.
5866
# For debug builds always builds with some optimization
59-
opt-level = "z"
67+
opt-level = "s"
6068

6169
[profile.release]
6270
codegen-units = 1 # LLVM can perform better optimizations using a single thread
@@ -67,24 +75,26 @@ overflow-checks = false
6775

6876
[features]
6977
default = ["esp32c6"]
70-
esp32 = ["esp-rtos/esp32", "esp-hal/esp32", "esp-backtrace/esp32", "esp-println/esp32", "esp-radio/esp32", "esp-bootloader-esp-idf/esp32", "esp-metadata-generated/esp32", "portable-atomic/critical-section", "wifi"]
71-
esp32c2 = ["esp-rtos/esp32c2", "esp-hal/esp32c2", "esp-backtrace/esp32c2", "esp-println/esp32c2", "esp-radio/esp32c2", "esp-bootloader-esp-idf/esp32c2", "esp-metadata-generated/esp32c2", "portable-atomic/critical-section", "wifi"]
72-
esp32c3 = ["esp-rtos/esp32c3", "esp-hal/esp32c3", "esp-backtrace/esp32c3", "esp-println/esp32c3", "esp-radio/esp32c3", "esp-bootloader-esp-idf/esp32c3", "esp-metadata-generated/esp32c3", "portable-atomic/unsafe-assume-single-core", "wifi"]
73-
esp32c6 = ["esp-rtos/esp32c6", "esp-hal/esp32c6", "esp-backtrace/esp32c6", "esp-println/esp32c6", "esp-radio/esp32c6", "esp-bootloader-esp-idf/esp32c6", "esp-metadata-generated/esp32c6", "portable-atomic/critical-section"]
74-
esp32s3 = ["esp-rtos/esp32s3", "esp-hal/esp32s3", "esp-backtrace/esp32s3", "esp-println/esp32s3", "esp-radio/esp32s3", "esp-bootloader-esp-idf/esp32s3", "esp-metadata-generated/esp32s3", "portable-atomic/critical-section", "wifi"]
75-
esp32h2 = ["esp-rtos/esp32h2", "esp-hal/esp32h2", "esp-backtrace/esp32h2", "esp-println/esp32h2", "esp-radio/esp32h2", "esp-bootloader-esp-idf/esp32h2", "esp-metadata-generated/esp32h2", "portable-atomic/critical-section", "thread"]
78+
esp32 = ["esp-rtos/esp32", "esp-hal/esp32", "esp-backtrace/esp32", "esp-println/esp32", "esp-radio/esp32", "esp-storage/esp32", "esp-bootloader-esp-idf/esp32", "esp-metadata-generated/esp32", "portable-atomic/critical-section", "wifi"]
79+
esp32c2 = ["esp-rtos/esp32c2", "esp-hal/esp32c2", "esp-backtrace/esp32c2", "esp-println/esp32c2", "esp-radio/esp32c2", "esp-storage/esp32c2", "esp-bootloader-esp-idf/esp32c2", "esp-metadata-generated/esp32c2", "portable-atomic/critical-section", "wifi"]
80+
esp32c3 = ["esp-rtos/esp32c3", "esp-hal/esp32c3", "esp-backtrace/esp32c3", "esp-println/esp32c3", "esp-radio/esp32c3", "esp-storage/esp32c3", "esp-bootloader-esp-idf/esp32c3", "esp-metadata-generated/esp32c3", "portable-atomic/unsafe-assume-single-core", "wifi"]
81+
esp32c6 = ["esp-rtos/esp32c6", "esp-hal/esp32c6", "esp-backtrace/esp32c6", "esp-println/esp32c6", "esp-radio/esp32c6", "esp-storage/esp32c6", "esp-bootloader-esp-idf/esp32c6", "esp-metadata-generated/esp32c6", "portable-atomic/critical-section"]
82+
esp32s3 = ["esp-rtos/esp32s3", "esp-hal/esp32s3", "esp-backtrace/esp32s3", "esp-println/esp32s3", "esp-radio/esp32s3", "esp-storage/esp32s3", "esp-bootloader-esp-idf/esp32s3", "esp-metadata-generated/esp32s3", "portable-atomic/critical-section", "wifi"]
83+
esp32h2 = ["esp-rtos/esp32h2", "esp-hal/esp32h2", "esp-backtrace/esp32h2", "esp-println/esp32h2", "esp-radio/esp32h2", "esp-storage/esp32h2", "esp-bootloader-esp-idf/esp32h2", "esp-metadata-generated/esp32h2", "portable-atomic/critical-section", "thread"]
7684
wifi = ["rs-matter-embassy/embassy-net"]
7785
thread = ["rs-matter-embassy/openthread"]
7886

7987
[dependencies]
8088
log = "0.4"
8189
embassy-executor = "0.9"
90+
embassy-embedded-hal = "0.3"
8291
esp-backtrace = { version = "0.18.1", features = ["panic-handler", "println"] }
8392
esp-hal = { version = "1", features = ["log-04", "unstable", "exception-handler"] }
8493
esp-rtos = { version = "0.2", features = ["esp-radio", "embassy"] }
8594
esp-alloc = { version = "0.9" }
8695
esp-println = { version = "0.16", features = ["log-04"] }
8796
esp-radio = { version = "0.17", features = ["ble", "log-04", "unstable"] }
97+
esp-storage = "0.8"
8898
esp-bootloader-esp-idf = { version = "0.4", features = ["log-04"] }
8999
esp-metadata-generated = "0.3"
90100
rs-matter-embassy = { path = "../../rs-matter-embassy", features = ["esp", "log"] }

examples/esp/src/bin/light_eth.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@ use rs_matter_embassy::matter::dm::devices::test::{
3737
};
3838
use rs_matter_embassy::matter::dm::devices::DEV_TYPE_ON_OFF_LIGHT;
3939
use rs_matter_embassy::matter::dm::{Async, Dataver, EmptyHandler, Endpoint, EpClMatcher, Node};
40+
use rs_matter_embassy::matter::persist::DummyKvBlobStore;
4041
use rs_matter_embassy::matter::utils::init::InitMaybeUninit;
4142
use rs_matter_embassy::matter::utils::select::Coalesce;
4243
use rs_matter_embassy::matter::{clusters, devices};
43-
use rs_matter_embassy::stack::persist::DummyKvBlobStore;
4444
use rs_matter_embassy::stack::rand::reseeding_csprng;
4545
use rs_matter_embassy::stack::utils::futures::IntoFaillble;
4646

@@ -151,13 +151,14 @@ async fn main(_s: Spawner) {
151151
Async(desc::DescHandler::new(Dataver::new_rand(&mut weak_rand)).adapt()),
152152
);
153153

154-
// Create the persister & load any previously saved state
155-
// `EmbassyPersist`+`EmbassyKvBlobStore` saves to a user-supplied NOR Flash region
156-
// However, for this demo and for simplicity, we use a dummy persister that does nothing
157-
let persist = stack
158-
.create_persist_with_comm_window(&crypto, DummyKvBlobStore)
159-
.await
160-
.unwrap();
154+
// Create a KV BLOB store and load any previously saved state of `rs-matter`
155+
// `SeqMapKvBlobStore` saves to a user-supplied NOR Flash region
156+
// However, for this demo and for simplicity, we use a dummy KV BLOB store that does nothing
157+
let mut kv = DummyKvBlobStore;
158+
stack.startup(&crypto, &mut kv).await.unwrap();
159+
160+
// Wrap the KV BLOB store as a shared reference, so that it can be used both by `rs-matter` and the user
161+
let kv = stack.create_shared_kv(kv).unwrap();
161162

162163
// Run the Matter stack with our handler
163164
// Using `pin!` is completely optional, but reduces the size of the final future
@@ -168,12 +169,12 @@ async fn main(_s: Spawner) {
168169
weak_rand,
169170
stack,
170171
),
171-
// The Matter stack needs a persister to store its state
172-
&persist,
173172
// The crypto provider
174173
&crypto,
175174
// Our `AsyncHandler` + `AsyncMetadata` impl
176175
(NODE, handler),
176+
// The Matter stack needs a blob store to store its state
177+
&kv,
177178
// No user future to run
178179
(),
179180
));

examples/esp/src/bin/light_eth2.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,14 @@ use rs_matter_embassy::matter::dm::devices::test::{
3636
};
3737
use rs_matter_embassy::matter::dm::devices::DEV_TYPE_ON_OFF_LIGHT;
3838
use rs_matter_embassy::matter::dm::{Async, Dataver, EmptyHandler, Endpoint, EpClMatcher, Node};
39+
use rs_matter_embassy::matter::persist::DummyKvBlobStore;
3940
use rs_matter_embassy::matter::utils::init::InitMaybeUninit;
4041
use rs_matter_embassy::matter::utils::select::Coalesce;
4142
use rs_matter_embassy::matter::{clusters, devices, BasicCommData};
4243
use rs_matter_embassy::ot::openthread::esp::EspRadio;
4344
use rs_matter_embassy::ot::openthread::{OpenThread, RamSettings};
4445
use rs_matter_embassy::ot::{OtMatterResources, OtMdns, OtNetStack, OtNetif};
4546
use rs_matter_embassy::stack::eth::EthMatterStack;
46-
use rs_matter_embassy::stack::persist::DummyKvBlobStore;
4747
use rs_matter_embassy::stack::rand::{reseeding_csprng, RngAdaptor};
4848

4949
use tinyrlibc as _;
@@ -189,13 +189,14 @@ async fn main(_s: Spawner) {
189189
Async(desc::DescHandler::new(Dataver::new_rand(&mut weak_rand)).adapt()),
190190
);
191191

192-
// Create the persister & load any previously saved state
193-
// `EmbassyPersist`+`EmbassyKvBlobStore` saves to a user-supplied NOR Flash region
194-
// However, for this demo and for simplicity, we use a dummy persister that does nothing
195-
let persist = stack
196-
.create_persist_with_comm_window(&crypto, DummyKvBlobStore)
197-
.await
198-
.unwrap();
192+
// Create a KV BLOB store and load any previously saved state of `rs-matter`
193+
// `SeqMapKvBlobStore` saves to a user-supplied NOR Flash region
194+
// However, for this demo and for simplicity, we use a dummy KV BLOB store that does nothing
195+
let mut kv = DummyKvBlobStore;
196+
stack.startup(&crypto, &mut kv).await.unwrap();
197+
198+
// Wrap the KV BLOB store as a shared reference, so that it can be used both by `rs-matter` and the user
199+
let kv = stack.create_shared_kv(kv).unwrap();
199200

200201
// Run the Matter stack with our handler
201202
// Using `pin!` is completely optional, but reduces the size of the final future
@@ -206,12 +207,12 @@ async fn main(_s: Spawner) {
206207
OtNetif::new(ot.clone()),
207208
// The Matter stack needs an mDNS instance to run
208209
OtMdns::new(ot.clone()),
209-
// The Matter stack needs a persister to store its state
210-
&persist,
211210
// The crypto provider
212211
&crypto,
213212
// Our `AsyncHandler` + `AsyncMetadata` impl
214213
(NODE, handler),
214+
// The Matter stack needs a blob store to store its state
215+
&kv,
215216
// No user future to run
216217
(),
217218
));

examples/esp/src/bin/light_thread.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ use rs_matter_embassy::matter::dm::devices::test::{
3333
};
3434
use rs_matter_embassy::matter::dm::devices::DEV_TYPE_ON_OFF_LIGHT;
3535
use rs_matter_embassy::matter::dm::{Async, Dataver, EmptyHandler, Endpoint, EpClMatcher, Node};
36+
use rs_matter_embassy::matter::persist::DummyKvBlobStore;
3637
use rs_matter_embassy::matter::utils::init::InitMaybeUninit;
3738
use rs_matter_embassy::matter::{clusters, devices, BasicCommData};
38-
use rs_matter_embassy::stack::persist::DummyKvBlobStore;
3939
use rs_matter_embassy::stack::rand::reseeding_csprng;
4040
use rs_matter_embassy::wireless::esp::EspThreadDriver;
4141
use rs_matter_embassy::wireless::{EmbassyThread, EmbassyThreadMatterStack};
@@ -157,13 +157,14 @@ async fn main(_s: Spawner) {
157157
Async(desc::DescHandler::new(Dataver::new_rand(&mut weak_rand)).adapt()),
158158
);
159159

160-
// Create the persister & load any previously saved state
161-
// `EmbassyPersist`+`EmbassyKvBlobStore` saves to a user-supplied NOR Flash region
162-
// However, for this demo and for simplicity, we use a dummy persister that does nothing
163-
let persist = stack
164-
.create_persist_with_comm_window(&crypto, DummyKvBlobStore)
165-
.await
166-
.unwrap();
160+
// Create a KV BLOB store and load any previously saved state of `rs-matter`
161+
// `SeqMapKvBlobStore` saves to a user-supplied NOR Flash region
162+
// However, for this demo and for simplicity, we use a dummy KV BLOB store that does nothing
163+
let mut kv = DummyKvBlobStore;
164+
stack.startup(&crypto, &mut kv).await.unwrap();
165+
166+
// Wrap the KV BLOB store as a shared reference, so that it can be used both by `rs-matter` and the user
167+
let kv = stack.create_shared_kv(kv).unwrap();
167168

168169
// Run the Matter stack with our handler
169170
// Using `pin!` is completely optional, but reduces the size of the final future
@@ -175,16 +176,16 @@ async fn main(_s: Spawner) {
175176
EspThreadDriver::new(peripherals.IEEE802154, peripherals.BT),
176177
crypto.rand().unwrap(),
177178
ieee_eui64,
178-
persist.store(),
179+
&kv,
179180
stack,
180181
true, // Use a random BLE address
181182
),
182-
// The Matter stack needs a persister to store its state
183-
&persist,
184183
// The crypto provider
185184
&crypto,
186185
// Our `AsyncHandler` + `AsyncMetadata` impl
187186
(NODE, handler),
187+
// The Matter stack needs a blob store to store its state
188+
&kv,
188189
// No user future to run
189190
(),
190191
));

examples/esp/src/bin/light_thread_coex.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ use rs_matter_embassy::matter::dm::devices::test::{
3434
};
3535
use rs_matter_embassy::matter::dm::devices::DEV_TYPE_ON_OFF_LIGHT;
3636
use rs_matter_embassy::matter::dm::{Async, Dataver, EmptyHandler, Endpoint, EpClMatcher, Node};
37+
use rs_matter_embassy::matter::persist::DummyKvBlobStore;
3738
use rs_matter_embassy::matter::utils::init::InitMaybeUninit;
3839
use rs_matter_embassy::matter::{clusters, devices, BasicCommData};
39-
use rs_matter_embassy::stack::persist::DummyKvBlobStore;
4040
use rs_matter_embassy::stack::rand::reseeding_csprng;
4141
use rs_matter_embassy::wireless::esp::EspThreadDriver;
4242
use rs_matter_embassy::wireless::{EmbassyThread, EmbassyThreadMatterStack};
@@ -158,13 +158,14 @@ async fn main(_s: Spawner) {
158158
Async(desc::DescHandler::new(Dataver::new_rand(&mut weak_rand)).adapt()),
159159
);
160160

161-
// Create the persister & load any previously saved state
162-
// `EmbassyPersist`+`EmbassyKvBlobStore` saves to a user-supplied NOR Flash region
163-
// However, for this demo and for simplicity, we use a dummy persister that does nothing
164-
let persist = stack
165-
.create_persist_with_comm_window(&crypto, DummyKvBlobStore)
166-
.await
167-
.unwrap();
161+
// Create a KV BLOB store and load any previously saved state of `rs-matter`
162+
// `SeqMapKvBlobStore` saves to a user-supplied NOR Flash region
163+
// However, for this demo and for simplicity, we use a dummy KV BLOB store that does nothing
164+
let mut kv = DummyKvBlobStore;
165+
stack.startup(&crypto, &mut kv).await.unwrap();
166+
167+
// Wrap the KV BLOB store as a shared reference, so that it can be used both by `rs-matter` and the user
168+
let kv = stack.create_shared_kv(kv).unwrap();
168169

169170
// Run the Matter stack with our handler
170171
// Using `pin!` is completely optional, but reduces the size of the final future
@@ -176,16 +177,16 @@ async fn main(_s: Spawner) {
176177
EspThreadDriver::new(peripherals.IEEE802154, peripherals.BT),
177178
crypto.rand().unwrap(),
178179
ieee_eui64,
179-
persist.store(),
180+
&kv,
180181
stack,
181182
true, // Use a random BLE address
182183
),
183-
// The Matter stack needs a persister to store its state
184-
&persist,
185184
// The crypto provider
186185
&crypto,
187186
// Our `AsyncHandler` + `AsyncMetadata` impl
188187
(NODE, handler),
188+
// The Matter stack needs a blob store to store its state
189+
&kv,
189190
// No user future to run
190191
(),
191192
));

examples/esp/src/bin/light_wifi.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ use rs_matter_embassy::matter::dm::devices::test::{
3636
};
3737
use rs_matter_embassy::matter::dm::devices::DEV_TYPE_ON_OFF_LIGHT;
3838
use rs_matter_embassy::matter::dm::{Async, Dataver, EmptyHandler, Endpoint, EpClMatcher, Node};
39+
use rs_matter_embassy::matter::persist::DummyKvBlobStore;
3940
use rs_matter_embassy::matter::utils::init::InitMaybeUninit;
4041
use rs_matter_embassy::matter::{clusters, devices};
41-
use rs_matter_embassy::stack::persist::DummyKvBlobStore;
4242
use rs_matter_embassy::stack::rand::reseeding_csprng;
4343
use rs_matter_embassy::wireless::esp::EspWifiDriver;
4444
use rs_matter_embassy::wireless::{EmbassyWifi, EmbassyWifiMatterStack};
@@ -143,13 +143,14 @@ async fn main(_s: Spawner) {
143143
Async(desc::DescHandler::new(Dataver::new_rand(&mut weak_rand)).adapt()),
144144
);
145145

146-
// Create the persister & load any previously saved state
147-
// `EmbassyPersist`+`EmbassyKvBlobStore` saves to a user-supplied NOR Flash region
148-
// However, for this demo and for simplicity, we use a dummy persister that does nothing
149-
let persist = stack
150-
.create_persist_with_comm_window(&crypto, DummyKvBlobStore)
151-
.await
152-
.unwrap();
146+
// Create a KV BLOB store and load any previously saved state of `rs-matter`
147+
// `SeqMapKvBlobStore` saves to a user-supplied NOR Flash region
148+
// However, for this demo and for simplicity, we use a dummy KV BLOB store that does nothing
149+
let mut kv = DummyKvBlobStore;
150+
stack.startup(&crypto, &mut kv).await.unwrap();
151+
152+
// Wrap the KV BLOB store as a shared reference, so that it can be used both by `rs-matter` and the user
153+
let kv = stack.create_shared_kv(kv).unwrap();
153154

154155
// Run the Matter stack with our handler
155156
// Using `pin!` is completely optional, but reduces the size of the final future
@@ -163,12 +164,12 @@ async fn main(_s: Spawner) {
163164
true, // Use a random BLE address
164165
stack,
165166
),
166-
// The Matter stack needs a persister to store its state
167-
&persist,
168167
// The crypto provider
169168
&crypto,
170169
// Our `AsyncHandler` + `AsyncMetadata` impl
171170
(NODE, handler),
171+
// The Matter stack needs a blob store to store its state
172+
&kv,
172173
// No user future to run
173174
(),
174175
));

0 commit comments

Comments
 (0)