Skip to content

Commit

Permalink
Zk battleship (gear-foundation#372)
Browse files Browse the repository at this point in the history
  • Loading branch information
MedovTimur authored Sep 2, 2024
1 parent 57fce69 commit 4eadf50
Show file tree
Hide file tree
Showing 33 changed files with 6,809 additions and 610 deletions.
1,792 changes: 1,184 additions & 608 deletions contracts/Cargo.lock

Large diffs are not rendered by default.

7 changes: 5 additions & 2 deletions contracts/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ members = [
"vara-man",
"varatube",
"w3bstreaming",

"zk-battleship/app",
"zk-battleship/wasm",
# Noncontract crates

"gear-lib",
Expand Down Expand Up @@ -225,8 +226,10 @@ gstd = "1.5.0"
gear-wasm-builder = "1.5.0"
gmeta = "1.5.0"
gclient = "1.5.0"
gtest = "1.4.2"
gtest = "1.5.0"
gear-core = "1.5.0"
sails-idl-gen = "0.3.0"
sails-rs = "0.3.0"

# External

Expand Down
30 changes: 30 additions & 0 deletions contracts/zk-battleship/app/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
[package]
name = "zk-battleship"
version.workspace = true
edition.workspace = true
license.workspace = true

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
gstd = { workspace = true, features = ["debug"] }
primitive-types.workspace = true
sails-rs.workspace = true
schnorrkel.workspace = true
gbuiltin-bls381 = { git = "https://github.com/gear-tech/gear", tag = "v1.3.0" }

[features]
debug = ["gstd/debug"]

[dev-dependencies]
env_logger = "*"
gtest.workspace = true
gear-core.workspace = true
gclient.workspace = true
hex-literal = "0.3.4"
tokio = "1"
gbuiltin-bls381 = { git = "https://github.com/gear-tech/gear", tag = "v1.3.0" }
ark-groth16 = { version = "0.4" }
ark-std = { version = "0.4" }


46 changes: 46 additions & 0 deletions contracts/zk-battleship/app/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#![no_std]
#![allow(dead_code)]
#![allow(clippy::new_without_default)]
#![allow(clippy::result_unit_err)]
#![allow(clippy::should_implement_trait)]
#![allow(clippy::too_many_arguments)]
use gstd::{msg, ActorId};
use sails_rs::gstd::program;
use services::{admin, multiple, session, single, verify::VerifyingKeyBytes};
pub mod services;

pub struct Program(());

#[program]
impl Program {
pub fn new(
builtin_bls381: ActorId,
verification_key_for_start: VerifyingKeyBytes,
verification_key_for_move: VerifyingKeyBytes,
config: admin::storage::configuration::Configuration,
) -> Self {
admin::AdminService::seed(
msg::source(),
builtin_bls381,
verification_key_for_start,
verification_key_for_move,
config,
);
session::SessionService::seed();
single::SingleService::seed();
multiple::MultipleService::seed();
Self(())
}
pub fn admin(&self) -> admin::AdminService {
admin::AdminService::new()
}
pub fn single(&self) -> single::SingleService {
single::SingleService::new()
}
pub fn multiple(&self) -> multiple::MultipleService {
multiple::MultipleService::new()
}
pub fn session(&self) -> session::SessionService {
session::SessionService::new()
}
}
195 changes: 195 additions & 0 deletions contracts/zk-battleship/app/src/services/admin/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
use self::storage::{
admin::AdminStorage, builtin_bls381::BuiltinStorage, configuration::Configuration,
verification_key::VerificationKeyStorage,
};
use crate::services;
use crate::VerifyingKeyBytes;
use core::fmt::Debug;
use gstd::{exec, msg, ActorId, Decode, Encode, String, TypeInfo, Vec};
use sails_rs::gstd::service;
use sails_rs::{format, Box};
use storage::configuration::ConfigurationStorage;

pub mod storage;

#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Encode, Decode, TypeInfo)]
#[codec(crate = sails_rs::scale_codec)]
#[scale_info(crate = sails_rs::scale_info)]
pub enum Event {
GameDeleted,
GamesDeleted,
AdminChanged,
BuiltinAddressChanged,
VerificationKeyChanged,
ConfigurationChanged,
Killed { inheritor: ActorId },
}

#[derive(Clone)]
pub struct AdminService(());

impl AdminService {
pub fn seed(
admin: ActorId,
builtin_bls381: ActorId,
verification_key_for_start: services::verify::VerifyingKeyBytes,
verification_key_for_move: services::verify::VerifyingKeyBytes,
config: Configuration,
) -> Self {
let _res = AdminStorage::set(admin);
debug_assert!(_res.is_ok());
let _res = BuiltinStorage::set(builtin_bls381);
debug_assert!(_res.is_ok());
let _res =
VerificationKeyStorage::set(verification_key_for_start, verification_key_for_move);
debug_assert!(_res.is_ok());
let _res = ConfigurationStorage::set(config);
debug_assert!(_res.is_ok());
Self(())
}
}

#[service(events = Event)]
impl AdminService {
pub fn new() -> Self {
Self(())
}

pub fn delete_single_game(&mut self, player_address: ActorId) {
Self::check_admin(msg::source());
services::single::storage::SingleGamesStorage::as_mut().remove(&player_address);
self.notify_on(Event::GameDeleted)
.expect("Notification Error");
}
pub fn delete_single_games(&mut self, time: u64) {
Self::check_admin(msg::source());
let games = services::single::storage::SingleGamesStorage::as_mut();
let current_time = exec::block_timestamp();
games.retain(|_id, game| (current_time - game.start_time) <= time);
self.notify_on(Event::GamesDeleted)
.expect("Notification Error");
}
pub fn delete_multiple_game(&mut self, game_id: ActorId) {
Self::check_admin(msg::source());
services::multiple::storage::MultipleGamesStorage::as_mut().remove(&game_id);
services::multiple::storage::GamePairsStorage::as_mut().retain(|_, &mut id| id != game_id);
self.notify_on(Event::GameDeleted)
.expect("Notification Error");
}
pub fn delete_multiple_games_by_time(&mut self, time: u64) {
Self::check_admin(msg::source());
let games = services::multiple::storage::MultipleGamesStorage::as_mut();
let current_time = exec::block_timestamp();
let mut ids_to_remove = Vec::new();

games.retain(|id, game| match game.start_time {
Some(start_time) => {
if (current_time - start_time) > time {
ids_to_remove.push(*id);
false
} else {
true
}
}
None => true,
});

let game_pairs = services::multiple::storage::GamePairsStorage::as_mut();
for id in ids_to_remove {
game_pairs.retain(|_, &mut game_id| game_id != id);
}
self.notify_on(Event::GamesDeleted)
.expect("Notification Error");
}

pub fn delete_multiple_games_in_batches(&mut self, divider: u64) {
Self::check_admin(msg::source());
let games = services::multiple::storage::MultipleGamesStorage::as_mut();
let mut count = 0;
let mut ids_to_remove = Vec::new();

games.retain(|id, _game| {
count += 1;
if count % divider == 0 {
ids_to_remove.push(*id);
false
} else {
true
}
});

let game_pairs = services::multiple::storage::GamePairsStorage::as_mut();
for id in ids_to_remove {
game_pairs.retain(|_, &mut game_id| game_id != id);
}
self.notify_on(Event::GamesDeleted)
.expect("Notification Error");
}
pub fn change_admin(&mut self, new_admin: ActorId) {
Self::check_admin(msg::source());
let admin = AdminStorage::get_mut();
*admin = new_admin;
self.notify_on(Event::AdminChanged)
.expect("Notification Error");
}
pub fn change_builtin_address(&mut self, new_builtin_address: ActorId) {
Self::check_admin(msg::source());
let builtin = BuiltinStorage::get_mut();
*builtin = new_builtin_address;
self.notify_on(Event::BuiltinAddressChanged)
.expect("Notification Error");
}
pub fn change_configuration(&mut self, configuration: Configuration) {
Self::check_admin(msg::source());
let config = ConfigurationStorage::get_mut();
*config = configuration;
self.notify_on(Event::ConfigurationChanged)
.expect("Notification Error");
}
pub fn change_verification_key(
&mut self,
new_vk_for_start: Option<services::verify::VerifyingKeyBytes>,
new_vk_for_move: Option<services::verify::VerifyingKeyBytes>,
) {
Self::check_admin(msg::source());
if let Some(new_vk) = new_vk_for_start {
let vk_for_start = VerificationKeyStorage::get_mut_vk_for_start();
*vk_for_start = new_vk;
}
if let Some(new_vk) = new_vk_for_move {
let vk_for_move = VerificationKeyStorage::get_mut_vk_for_move();
*vk_for_move = new_vk;
}
self.notify_on(Event::VerificationKeyChanged)
.expect("Notification Error");
}

pub fn kill(&mut self, inheritor: ActorId) {
Self::check_admin(msg::source());
self.notify_on(Event::Killed { inheritor })
.expect("Notification Error");
exec::exit(inheritor);
}
fn check_admin(source: ActorId) {
assert!(
source == AdminStorage::get(),
"No permission to call this function"
);
}

pub fn admin(&self) -> ActorId {
AdminStorage::get()
}
pub fn builtin(&self) -> ActorId {
BuiltinStorage::get()
}
pub fn configuration(&self) -> Configuration {
ConfigurationStorage::get()
}
pub fn verification_key(&self) -> (VerifyingKeyBytes, VerifyingKeyBytes) {
(
VerificationKeyStorage::get_vk_for_start().clone(),
VerificationKeyStorage::get_vk_for_move().clone(),
)
}
}
Loading

0 comments on commit 4eadf50

Please sign in to comment.