Skip to content

Commit

Permalink
fix: state sync (#969)
Browse files Browse the repository at this point in the history
  • Loading branch information
miraclx authored Nov 26, 2024
1 parent db551eb commit 55c6121
Show file tree
Hide file tree
Showing 34 changed files with 1,905 additions and 2,119 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion apps/gen-ext/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ version = "0.1.0"
crate-type = ["cdylib"]

[dependencies]
calimero-sdk = {path = "../../crates/sdk"}
calimero-sdk = { path = "../../crates/sdk" }
calimero-sdk-near = { path = "../../crates/sdk/libs/near" }
calimero-storage = { path = "../../crates/storage" }
85 changes: 0 additions & 85 deletions apps/kv-store/src/__private.rs

This file was deleted.

20 changes: 8 additions & 12 deletions apps/kv-store/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,16 @@

use std::collections::BTreeMap;

use calimero_sdk::borsh::{BorshDeserialize, BorshSerialize};
use calimero_sdk::types::Error;
use calimero_sdk::{app, env};
use calimero_storage::collections::UnorderedMap;
use calimero_storage::entities::Element;
use calimero_storage::AtomicUnit;

mod __private;

#[app::state(emits = for<'a> Event<'a>)]
#[derive(AtomicUnit, Clone, Debug, PartialEq, PartialOrd)]
#[root]
#[type_id(1)]
#[derive(Debug, PartialEq, PartialOrd, BorshSerialize, BorshDeserialize)]
#[borsh(crate = "calimero_sdk::borsh")]
pub struct KvStore {
items: UnorderedMap<String, String>,
#[storage]
storage: Element,
}

#[app::event]
Expand All @@ -33,8 +27,7 @@ impl KvStore {
#[app::init]
pub fn init() -> KvStore {
KvStore {
items: UnorderedMap::new().unwrap(),
storage: Element::root(),
items: UnorderedMap::new(),
}
}

Expand Down Expand Up @@ -93,7 +86,10 @@ impl KvStore {

app::emit!(Event::Removed { key });

self.items.remove(key).map_err(Into::into)
self.items
.remove(key)
.map(|v| v.is_some())
.map_err(Into::into)
}

pub fn clear(&mut self) -> Result<(), Error> {
Expand Down
1 change: 1 addition & 0 deletions apps/only-peers/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ crate-type = ["cdylib"]

[dependencies]
calimero-sdk = { path = "../../crates/sdk" }
calimero-storage = { path = "../../crates/storage" }
44 changes: 26 additions & 18 deletions apps/only-peers/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
use calimero_sdk::borsh::{BorshDeserialize, BorshSerialize};
use calimero_sdk::serde::Serialize;
use calimero_sdk::types::Error;
use calimero_sdk::{app, env};
use calimero_storage::collections::Vector;

#[app::state(emits = for<'a> Event<'a>)]
#[derive(BorshDeserialize, BorshSerialize, Default)]
#[borsh(crate = "calimero_sdk::borsh")]
pub struct OnlyPeers {
posts: Vec<Post>,
posts: Vector<Post>,
}

#[derive(BorshDeserialize, BorshSerialize, Default, Serialize)]
Expand All @@ -16,10 +18,10 @@ pub struct Post {
id: usize,
title: String,
content: String,
comments: Vec<Comment>,
comments: Vector<Comment>,
}

#[derive(BorshDeserialize, BorshSerialize, Default, Serialize)]
#[derive(BorshDeserialize, BorshSerialize, Clone, Default, Serialize)]
#[borsh(crate = "calimero_sdk::borsh")]
#[serde(crate = "calimero_sdk::serde")]
pub struct Comment {
Expand Down Expand Up @@ -48,40 +50,40 @@ impl OnlyPeers {
OnlyPeers::default()
}

pub fn post(&self, id: usize) -> Option<&Post> {
pub fn post(&self, id: usize) -> Result<Option<Post>, Error> {
env::log(&format!("Getting post with id: {:?}", id));

self.posts.get(id)
Ok(self.posts.get(id)?)
}

pub fn posts(&self) -> &[Post] {
pub fn posts(&self) -> Result<Vec<Post>, Error> {
env::log("Getting all posts");

&self.posts
Ok(self.posts.entries()?.collect())
}

pub fn create_post(&mut self, title: String, content: String) -> &Post {
pub fn create_post(&mut self, title: String, content: String) -> Result<Post, Error> {
env::log(&format!(
"Creating post with title: {:?} and content: {:?}",
title, content
));

app::emit!(Event::PostCreated {
id: self.posts.len(),
id: self.posts.len()?,
// todo! should we maybe only emit an ID, and let notified clients fetch the post?
title: &title,
content: &content,
});

self.posts.push(Post {
id: self.posts.len(),
id: self.posts.len()?,
title,
content,
comments: Vec::new(),
});
comments: Vector::new(),
})?;

match self.posts.last() {
Some(post) => post,
match self.posts.last()? {
Some(post) => Ok(post),
None => env::unreachable(),
}
}
Expand All @@ -91,13 +93,15 @@ impl OnlyPeers {
post_id: usize,
user: String, // todo! expose executor identity to app context
text: String,
) -> Option<&Comment> {
) -> Result<Option<Comment>, Error> {
env::log(&format!(
"Creating comment under post with id: {:?} as user: {:?} with text: {:?}",
post_id, user, text
));

let post = self.posts.get_mut(post_id)?;
let Some(mut post) = self.posts.get(post_id)? else {
return Ok(None);
};

app::emit!(Event::CommentCreated {
post_id,
Expand All @@ -106,8 +110,12 @@ impl OnlyPeers {
text: &text,
});

post.comments.push(Comment { user, text });
let comment = Comment { user, text };

post.comments.push(comment.clone())?;

self.posts.update(post_id, post)?;

post.comments.last()
Ok(Some(comment))
}
}
18 changes: 5 additions & 13 deletions apps/visited/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,28 @@
use std::result::Result;

use calimero_sdk::app;
use calimero_sdk::borsh::{BorshDeserialize, BorshSerialize};
use calimero_sdk::types::Error;
use calimero_storage::collections::{UnorderedMap, UnorderedSet};
use calimero_storage::entities::Element;
use calimero_storage::AtomicUnit;

#[app::state]
#[derive(AtomicUnit, Clone, Debug, PartialEq, PartialOrd)]
#[root]
#[type_id(1)]
#[derive(Debug, PartialEq, PartialOrd, BorshSerialize, BorshDeserialize)]
#[borsh(crate = "calimero_sdk::borsh")]
pub struct VisitedCities {
visited: UnorderedMap<String, UnorderedSet<String>>,
#[storage]
storage: Element,
}

#[app::logic]
impl VisitedCities {
#[app::init]
pub fn init() -> VisitedCities {
VisitedCities {
visited: UnorderedMap::new().unwrap(),
storage: Element::root(),
visited: UnorderedMap::new(),
}
}

pub fn add_person(&mut self, person: String) -> Result<bool, Error> {
Ok(self
.visited
.insert(person, UnorderedSet::new().unwrap())?
.is_some())
Ok(self.visited.insert(person, UnorderedSet::new())?.is_some())
}

pub fn add_visited_city(&mut self, person: String, city: String) -> Result<bool, Error> {
Expand Down
23 changes: 10 additions & 13 deletions crates/node/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,17 +346,12 @@ impl Node {

let shared_key = SharedKey::from_sk(&sender_key);

let artifact = &shared_key
let artifact = shared_key
.decrypt(artifact, nonce)
.ok_or_eyre("failed to decrypt message")?;

let Some(outcome) = self
.execute(
&mut context,
"apply_state_delta",
to_vec(&artifact)?,
author_id,
)
.execute(&mut context, "__calimero_sync_next", artifact, author_id)
.await?
else {
bail!("application not installed");
Expand Down Expand Up @@ -505,11 +500,13 @@ impl Node {
})?;
}

if let Err(err) = self
.send_state_delta(&context, &outcome, executor_public_key)
.await
{
error!(%err, "Failed to send state delta.");
if !outcome.artifact.is_empty() {
if let Err(err) = self
.send_state_delta(&context, &outcome, executor_public_key)
.await
{
error!(%err, "Failed to send state delta.");
}
}

Ok(outcome)
Expand Down Expand Up @@ -544,7 +541,7 @@ impl Node {

if outcome.returns.is_ok() {
if let Some(root_hash) = outcome.root_hash {
if outcome.artifact.is_empty() {
if outcome.artifact.is_empty() && method != "__calimero_sync_next" {
eyre::bail!("context state changed, but no actions were generated, discarding execution outcome to mitigate potential state inconsistency");
}

Expand Down
Loading

0 comments on commit 55c6121

Please sign in to comment.