Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ZKSaaS pallet #321

Merged
merged 11 commits into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions pallets/jobs/src/functions.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::*;
use sp_runtime::traits::Zero;
use tangle_primitives::jobs::{DKGJobType, JobKey, JobType, ZkSaasPhaseOneJobType};
use tangle_primitives::jobs::{DKGJobType, JobKey, JobType, ZkSaasCircuitJobType};

impl<T: Config> Pallet<T> {
/// Add a job ID to the validator lookup.
Expand Down Expand Up @@ -188,22 +188,34 @@ impl<T: Config> Pallet<T> {
};
SubmittedJobs::<T>::insert(job_key.clone(), job_id, job_info);
},
// Case for JobKey::ZkSaasPhaseTwo
// Case for JobKey::ZkSaasProve
// - Extract information from 'phase1'
// - Create a new 'job_type' of ZkSaasPhaseOneJobType with adjusted parameters
// (remove the reported validator)
// - Charge the validator fee for job submission
// - Store information about the submitted job in 'SubmittedJobs'
JobKey::ZkSaasPhaseTwo => {
JobKey::ZkSaasProve => {
let new_participants = phase1
.participants
.clone()
.into_iter()
.filter(|x| x != &validator)
.collect();
let phase_one_id = job_info
.job_type
.get_phase_one_id()
.ok_or(Error::<T>::PhaseOneResultNotFound)?;
let phase_one =
SubmittedJobs::<T>::get(JobKey::ZkSaasCircuit, phase_one_id)
.ok_or(Error::<T>::JobNotFound)?;
let system = match phase_one.job_type {
JobType::ZkSaasCircuit(ref info) => info.system.clone(),
_ => return Err(Error::<T>::JobNotFound.into()),
};

let job_type = JobType::ZkSaasPhaseOne(ZkSaasPhaseOneJobType {
let job_type = JobType::ZkSaasCircuit(ZkSaasCircuitJobType {
participants: new_participants,
system,
});

// charge the validator fee for job submission
Expand Down
4 changes: 2 additions & 2 deletions pallets/jobs/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ impl JobToFee<AccountId, BlockNumber> for MockJobToFeeHandler {
match job.job_type {
JobType::DKG(_) => MockDKGPallet::job_to_fee(job),
JobType::DKGSignature(_) => MockDKGPallet::job_to_fee(job),
JobType::ZkSaasPhaseOne(_) => MockZkSaasPallet::job_to_fee(job),
JobType::ZkSaasPhaseTwo(_) => MockZkSaasPallet::job_to_fee(job),
JobType::ZkSaasCircuit(_) => MockZkSaasPallet::job_to_fee(job),
JobType::ZkSaasProve(_) => MockZkSaasPallet::job_to_fee(job),
}
}
}
Expand Down
157 changes: 117 additions & 40 deletions primitives/src/types/jobs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,101 @@ pub enum JobType<AccountId> {
DKG(DKGJobType<AccountId>),
/// DKG Signature job type.
DKGSignature(DKGSignatureJobType),
/// (zk-SNARK) Phase One job type.
ZkSaasPhaseOne(ZkSaasPhaseOneJobType<AccountId>),
/// (zk-SNARK) Phase Two job type.
ZkSaasPhaseTwo(ZkSaasPhaseTwoJobType),
/// (zk-SNARK) Create Circuit job type.
ZkSaasCircuit(ZkSaasCircuitJobType<AccountId>),
/// (zk-SNARK) Create Proof job type.
ZkSaasProve(ZkSaasProveJobType),
}

/// Enum representing different types of data sources.
#[derive(PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub enum HyperData {
/// Raw data, stored on-chain.
///
/// Only use this for small files.
Raw(Vec<u8>),
shekohex marked this conversation as resolved.
Show resolved Hide resolved
/// IPFS CID. The CID is stored on-chain.
/// The actual data is stored off-chain.
IPFS(Vec<u8>),
/// HTTP URL. The URL is stored on-chain.
/// The actual data is stored off-chain.
/// The URL is expected to be accessible via HTTP GET.
HTTP(Vec<u8>),
}

/// Enum representing different types of circuits and snark schemes.
#[derive(PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub enum ZkSaasSystem {
Groth16(Groth16System),
Plonk(PlonkSystem),
}

/// Represents the Groth16 system for zk-SNARKs.
#[derive(PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct Groth16System {
/// R1CS circuit file.
pub circuit: HyperData,
/// Proving key file.
pub proving_key: HyperData,
/// Circom WASM file.
pub wasm: HyperData,
}

/// TODO: Add Plonk system
#[derive(PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct PlonkSystem {}
shekohex marked this conversation as resolved.
Show resolved Hide resolved

/// Represents ZK-SNARK proving request
#[derive(PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub enum ZkSaasProveRequest {
/// Groth16 proving request
Groth16(Groth16ProveRequest),
/// Plonk proving request
Plonk(PlonkProveRequest),
}

/// Represents Groth16 proving request
#[derive(PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct Groth16ProveRequest {
/// Public input that are used during the verification
pub public_input: Vec<HyperData>,
/// `a` is the full assignment (full_assginment[0] is 1)
/// a = full_assginment[1..]
/// Each element contains a PSS of the witness
pub a_shares: Vec<HyperData>,
/// `ax` is the auxiliary input
/// ax = full_assginment[num_inputs..]
/// Each element contains a PSS of the auxiliary input
pub ax: Vec<HyperData>,
/// PSS of the QAP polynomials
pub qap_shares: Vec<QAPShare>,
}

/// Represents QAP share
#[derive(PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct QAPShare {
pub a: HyperData,
pub b: HyperData,
pub c: HyperData,
}

/// TODO: Add Plonk proving request
#[derive(PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct PlonkProveRequest {}

impl<AccountId> JobType<AccountId> {
/// Checks if the job type is a phase one job.
pub fn is_phase_one(&self) -> bool {
use crate::jobs::JobType::*;
if matches!(self, DKG(_) | ZkSaasPhaseOne(_)) {
if matches!(self, DKG(_) | ZkSaasCircuit(_)) {
return true
}
false
Expand All @@ -76,7 +160,7 @@ impl<AccountId> JobType<AccountId> {
use crate::jobs::JobType::*;
match self {
DKG(info) => Some(info.participants),
ZkSaasPhaseOne(info) => Some(info.participants),
ZkSaasCircuit(info) => Some(info.participants),
_ => None,
}
}
Expand All @@ -94,17 +178,17 @@ impl<AccountId> JobType<AccountId> {
pub fn get_job_key(&self) -> JobKey {
match self {
JobType::DKG(_) => JobKey::DKG,
JobType::ZkSaasPhaseOne(_) => JobKey::ZkSaasPhaseOne,
JobType::ZkSaasCircuit(_) => JobKey::ZkSaasCircuit,
JobType::DKGSignature(_) => JobKey::DKGSignature,
JobType::ZkSaasPhaseTwo(_) => JobKey::ZkSaasPhaseTwo,
JobType::ZkSaasProve(_) => JobKey::ZkSaasProve,
}
}

/// Gets the job key associated with the previous phase job type.
pub fn get_previous_phase_job_key(&self) -> Option<JobKey> {
match self {
JobType::DKGSignature(_) => Some(JobKey::DKG),
JobType::ZkSaasPhaseTwo(_) => Some(JobKey::ZkSaasPhaseOne),
JobType::ZkSaasProve(_) => Some(JobKey::ZkSaasCircuit),
_ => None,
}
}
Expand All @@ -114,22 +198,18 @@ impl<AccountId> JobType<AccountId> {
/// This function is intended for simple checks and may need improvement in the future.
pub fn sanity_check(&self) -> bool {
match self {
JobType::DKG(info) =>
if info.participants.len() > info.threshold.into() {
return true
},
_ => return true,
JobType::DKG(info) => info.participants.len() > info.threshold.into(),
JobType::ZkSaasCircuit(info) => !info.participants.is_empty(),
_ => true,
}

false
}

/// Gets the phase one ID for phase two jobs, if applicable.
pub fn get_phase_one_id(self) -> Option<u32> {
pub fn get_phase_one_id(&self) -> Option<u32> {
use crate::jobs::JobType::*;
match self {
DKGSignature(info) => Some(info.phase_one_id),
ZkSaasPhaseTwo(info) => Some(info.phase_one_id),
ZkSaasProve(info) => Some(info.phase_one_id),
_ => None,
}
}
Expand Down Expand Up @@ -160,20 +240,22 @@ pub struct DKGSignatureJobType {
/// Represents the (zk-SNARK) Phase One job type.
#[derive(PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct ZkSaasPhaseOneJobType<AccountId> {
pub struct ZkSaasCircuitJobType<AccountId> {
/// List of participants' account IDs.
pub participants: Vec<AccountId>,
/// ZK-SNARK Proving system
pub system: ZkSaasSystem,
}

/// Represents the (zk-SNARK) Phase Two job type.
#[derive(PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct ZkSaasPhaseTwoJobType {
pub struct ZkSaasProveJobType {
/// The phase one ID.
pub phase_one_id: u32,

/// The submission data as a vector of bytes.
pub submission: Vec<u8>,
/// ZK-SNARK Proving request
pub request: ZkSaasProveRequest,
}

/// Enum representing different states of a job.
Expand All @@ -195,10 +277,10 @@ pub enum JobKey {
DKG,
/// DKG Signature job type.
DKGSignature,
/// (zk-SNARK) Phase One job type.
ZkSaasPhaseOne,
/// (zk-SNARK) Phase Two job type.
ZkSaasPhaseTwo,
/// (zk-SNARK) Create Circuit job type.
ZkSaasCircuit,
/// (zk-SNARK) Create Proof job type.
ZkSaasProve,
}

impl JobKey {
Expand All @@ -207,8 +289,8 @@ impl JobKey {
match self {
JobKey::DKG => RoleType::Tss,
JobKey::DKGSignature => RoleType::Tss,
JobKey::ZkSaasPhaseOne => RoleType::ZkSaas,
JobKey::ZkSaasPhaseTwo => RoleType::ZkSaas,
JobKey::ZkSaasCircuit => RoleType::ZkSaas,
JobKey::ZkSaasProve => RoleType::ZkSaas,
}
}
}
Expand Down Expand Up @@ -268,9 +350,9 @@ pub enum JobResult {

DKGSignature(DKGSignatureResult),

ZkSaasPhaseOne(ZkSaasPhaseOneResult),
ZkSaasCircuit(ZkSaasCircuitResult),

ZkSaasPhaseTwo(ZkSaasPhaseTwoResult),
ZkSaasProve(ZkSaasProofResult),
}

pub type KeysAndSignatures = Vec<(Vec<u8>, Vec<u8>)>;
Expand Down Expand Up @@ -306,23 +388,18 @@ pub struct DKGSignatureResult {

#[derive(PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct ZkSaasPhaseOneResult {
pub struct ZkSaasCircuitResult {
/// The job id of the job
pub job_id: JobId,

/// List of participants' public keys
pub participants: Vec<Vec<u8>>,

/// The data to verify
pub data: Vec<u8>,
}

#[derive(PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct ZkSaasPhaseTwoResult {
/// The data to verify
pub data: Vec<u8>,

/// The expected key for the signature
pub signing_key: Vec<u8>,
pub struct ZkSaasProofResult {
drewstone marked this conversation as resolved.
Show resolved Hide resolved
pub a: Vec<u8>,
pub b: Vec<u8>,
pub c: Vec<u8>,
}
Loading