Skip to content

Commit

Permalink
fix: contract call through account, impl: reward
Browse files Browse the repository at this point in the history
  • Loading branch information
rkdud007 committed May 6, 2024
1 parent f6e6f2b commit a962cd7
Show file tree
Hide file tree
Showing 13 changed files with 104 additions and 99 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ async-stream = "0.3.5"
bincode = "1.3"
cairo-proof-parser = { git = "https://github.com/Okm165/cairo-proof-parser", rev = "97a04bbee07330311b38d6f4cecfed3acb237626" }
cairo-vm = { git = "https://github.com/lambdaclass/cairo-vm.git" }
crypto-bigint = { version = "0.5.3", features = ["serde"] }
futures = "0.3.30"
futures-core = "0.3.30"
futures-util = "0.3.30"
Expand Down
3 changes: 2 additions & 1 deletion crates/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ license-file.workspace = true

[dependencies]
cairo-vm.workspace = true
crypto-bigint.workspace = true
futures.workspace = true
hex.workspace = true
libp2p.workspace = true
Expand All @@ -22,4 +23,4 @@ starknet.workspace = true
strum.workspace = true
tempfile.workspace = true
thiserror.workspace = true
tokio.workspace = true
tokio.workspace = true
15 changes: 7 additions & 8 deletions crates/common/src/job.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::hash;
use cairo_vm::vm::runners::cairo_pie::CairoPie;
use crypto_bigint::U256;
use serde::{Deserialize, Serialize};
use starknet::signers::{SigningKey, VerifyingKey};
use starknet_crypto::{poseidon_hash_many, FieldElement, Signature};
Expand Down Expand Up @@ -44,22 +45,20 @@ impl Job {

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct JobData {
pub reward: u64,
pub reward: U256,
pub num_of_steps: u64,
#[serde(with = "chunk_felt_array")]
pub cairo_pie_compressed: Vec<u8>,
pub registry_address: FieldElement,
}

impl JobData {
pub fn new(reward: u64, cairo_pie_compressed: Vec<u8>, registry_address: FieldElement) -> Self {
pub fn new(tip: u64, cairo_pie_compressed: Vec<u8>, registry_address: FieldElement) -> Self {
let pie = Self::decompress_cairo_pie(&cairo_pie_compressed);
Self {
reward,
num_of_steps: pie.execution_resources.n_steps as u64,
cairo_pie_compressed,
registry_address,
}
let num_of_steps = pie.execution_resources.n_steps as u64;
// TODO - calculate reward based on the number of steps and the tip
let reward = U256::from(num_of_steps * 100 + tip);
Self { reward, num_of_steps, cairo_pie_compressed, registry_address }
}

fn decompress_cairo_pie(cairo_pie_compressed: &[u8]) -> CairoPie {
Expand Down
1 change: 0 additions & 1 deletion crates/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ pub mod job_witness;
pub mod layout;
pub mod macros;
pub mod network;
pub mod node_account;
pub mod process;
pub mod topic;

Expand Down
31 changes: 14 additions & 17 deletions crates/compiler/src/cairo_compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,8 @@ use async_process::Stdio;
use futures::Future;
use rand::{thread_rng, Rng};
use serde_json::json;
use sharp_p2p_common::job::JobData;
use sharp_p2p_common::layout::Layout;
use sharp_p2p_common::{job::Job, process::Process};
use starknet::signers::SigningKey;
use starknet_crypto::FieldElement;
use sharp_p2p_common::process::Process;
use std::io::Write;
use std::path::PathBuf;
use std::{io::Read, pin::Pin};
Expand All @@ -17,25 +14,28 @@ use tracing::debug;

pub mod tests;

pub struct CairoCompiler<'identity> {
signing_key: &'identity SigningKey,
registry_contract: FieldElement,
pub struct CairoCompiler {}

impl CairoCompiler {
pub fn new() -> Self {
Self {}
}
}

impl<'identity> CairoCompiler<'identity> {
pub fn new(signing_key: &'identity SigningKey, registry_contract: FieldElement) -> Self {
Self { signing_key, registry_contract }
impl Default for CairoCompiler {
fn default() -> Self {
Self::new()
}
}

impl<'identity> CompilerController for CairoCompiler<'identity> {
impl CompilerController for CairoCompiler {
fn run(
&self,
program_path: PathBuf,
_program_input_path: PathBuf,
) -> Result<Process<Result<Job, CompilerControllerError>>, CompilerControllerError> {
) -> Result<Process<Result<Vec<u8>, CompilerControllerError>>, CompilerControllerError> {
let (terminate_tx, mut terminate_rx) = mpsc::channel::<()>(10);
let future: Pin<Box<dyn Future<Output = Result<Job, CompilerControllerError>> + '_>> =
let future: Pin<Box<dyn Future<Output = Result<Vec<u8>, CompilerControllerError>> + '_>> =
Box::pin(async move {
let layout: &str = Layout::RecursiveWithPoseidon.into();

Expand Down Expand Up @@ -118,10 +118,7 @@ impl<'identity> CompilerController for CairoCompiler<'identity> {
let mut cairo_pie_compressed = Vec::new();
cairo_pie.read_to_end(&mut cairo_pie_compressed)?;

Ok(Job::try_from_job_data(
JobData::new(0, cairo_pie_compressed, self.registry_contract),
self.signing_key,
))
Ok(cairo_pie_compressed)
});

Ok(Process::new(future, terminate_tx))
Expand Down
9 changes: 4 additions & 5 deletions crates/compiler/src/cairo_compiler/tests/single_job.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,20 @@ use crate::{
traits::CompilerController,
};
use starknet::signers::SigningKey;
use starknet_crypto::FieldElement;

#[tokio::test]
async fn run_single_job() {
let fixture = fixture();
let identity = SigningKey::from_random();
let compiler = CairoCompiler::new(&identity, FieldElement::ZERO);
let _identity = SigningKey::from_random();
let compiler = CairoCompiler::new();
compiler.run(fixture.program_path, fixture.program_input_path).unwrap().await.unwrap();
}

#[tokio::test]
async fn abort_single_jobs() {
let fixture = fixture();
let identity = SigningKey::from_random();
let compiler = CairoCompiler::new(&identity, FieldElement::ZERO);
let _identity = SigningKey::from_random();
let compiler = CairoCompiler::new();
let job = compiler.run(fixture.program_path, fixture.program_input_path).unwrap();
job.abort().await.unwrap();
job.await.unwrap_err();
Expand Down
9 changes: 4 additions & 5 deletions crates/compiler/src/traits.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
use crate::errors::CompilerControllerError;
use sharp_p2p_common::{job::Job, process::Process};
use sharp_p2p_common::process::Process;
use std::path::PathBuf;

/*
The `CompilerController` trait is responsible for taking a user's program and preparing a `Job` object.
This process involves compiling the user's code and creating a Cairo PIE (Proof-of-Inclusion-Execution) object from it.
The resulting `Job` object encapsulates the necessary information for later execution by a `RunnerController`.
The `run` method accepts the paths to the program and its input, returning a `Result` containing a `Process` object.
Upon successful completion, it yields a `Job` object, ready to be utilized by a `RunnerController` to execute the program.
The resulting `Vec<u8>` object that represents the Cairo PIE is then compressed and stored in the `JobData` object.
Later, the `Job` object is then signed by the delegator's private key and sent to the network for execution.
*/

pub trait CompilerController {
fn run(
&self,
program_path: PathBuf,
program_input_path: PathBuf,
) -> Result<Process<Result<Job, CompilerControllerError>>, CompilerControllerError>;
) -> Result<Process<Result<Vec<u8>, CompilerControllerError>>, CompilerControllerError>;
}
23 changes: 17 additions & 6 deletions crates/delegator/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ use futures::{stream::FuturesUnordered, StreamExt};
use libp2p::gossipsub::Event;
use sharp_p2p_common::{
hash,
job::Job,
job::{Job, JobData},
network::Network,
node_account::NodeAccount,
process::Process,
topic::{gossipsub_ident_topic, Topic},
};
Expand All @@ -15,7 +14,7 @@ use sharp_p2p_compiler::{
errors::CompilerControllerError,
traits::CompilerController,
};
use sharp_p2p_peer::{registry::RegistryHandler, swarm::SwarmRunner};
use sharp_p2p_peer::{node_account::NodeAccount, registry::RegistryHandler, swarm::SwarmRunner};
use starknet::providers::{jsonrpc::HttpTransport, JsonRpcClient, Url};
use std::hash::{DefaultHasher, Hash, Hasher};
use tokio::{
Expand Down Expand Up @@ -60,13 +59,15 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut message_stream = swarm_runner.run(new_job_topic, send_topic_rx);
let mut event_stream = registry_handler.subscribe_events(vec!["0x0".to_string()]);

let compiler = CairoCompiler::new(node_account.get_signing_key(), registry_address);
let compiler = CairoCompiler::new();

let mut compiler_scheduler =
FuturesUnordered::<Process<'_, Result<Job, CompilerControllerError>>>::new();
FuturesUnordered::<Process<'_, Result<Vec<u8>, CompilerControllerError>>>::new();

// Read cairo program path from stdin
let mut stdin = BufReader::new(stdin()).lines();
// TODO: Accept dynamic tip
let tip = 10;

loop {
tokio::select! {
Expand Down Expand Up @@ -104,7 +105,17 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
Some(Ok(event_vec)) = event_stream.next() => {
debug!("{:?}", event_vec);
},
Some(Ok(job)) = compiler_scheduler.next() => {
Some(Ok(cairo_pie_compressed)) = compiler_scheduler.next() => {
let job_data = JobData::new(tip, cairo_pie_compressed,registry_address);
let expected_reward = job_data.reward;
let staked_amount = node_account.balance(registry_address).await?;
// TODO: handle error better way
if staked_amount < expected_reward{
return Err("Staked amount is less than expected reward".into());
}
let job = Job::try_from_job_data(job_data, node_account.get_signing_key());
// info!("Job: {:?}", job.job_data.reward);
// info!("Job: {:?}", job.job_data.num_of_steps);
let serialized_job = serde_json::to_string(&job).unwrap();
send_topic_tx.send(serialized_job.into()).await?;
info!("Sent a new job: {}", hash!(&job));
Expand Down
3 changes: 1 addition & 2 deletions crates/executor/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ use sharp_p2p_common::{
job_trace::JobTrace,
job_witness::JobWitness,
network::Network,
node_account::NodeAccount,
process::Process,
topic::{gossipsub_ident_topic, Topic},
};
use sharp_p2p_peer::{registry::RegistryHandler, swarm::SwarmRunner};
use sharp_p2p_peer::{node_account::NodeAccount, registry::RegistryHandler, swarm::SwarmRunner};
use sharp_p2p_prover::{
errors::ProverControllerError, stone_prover::StoneProver, traits::ProverController,
};
Expand Down
1 change: 1 addition & 0 deletions crates/peer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ license-file.workspace = true

[dependencies]
async-stream.workspace = true
crypto-bigint.workspace = true
futures.workspace = true
libp2p.workspace = true
starknet.workspace = true
Expand Down
1 change: 1 addition & 0 deletions crates/peer/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod node_account;
pub mod registry;
pub mod swarm;
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
use std::error::Error;

use crypto_bigint::U256;
use sharp_p2p_common::network::Network;
use starknet::{
accounts::{ConnectedAccount, ExecutionEncoding, SingleOwnerAccount},
core::types::FieldElement,
accounts::{Account, Call, ConnectedAccount, ExecutionEncoding, SingleOwnerAccount},
core::types::{BlockId, BlockTag, FieldElement, FunctionCall},
macros::selector,
providers::Provider,
signers::{LocalWallet, SigningKey, VerifyingKey},
};

use crate::network::Network;
use tracing::trace;

pub struct NodeAccount<P>
where
Expand Down Expand Up @@ -62,4 +66,47 @@ where
pub fn get_verifying_key(&self) -> VerifyingKey {
self.signing_key.verifying_key()
}

pub async fn deposit(
&self,
amount: FieldElement,
registry_address: FieldElement,
) -> Result<(), Box<dyn Error>> {
let result = self
.account
.execute(vec![Call {
to: registry_address,
selector: selector!("deposit"),
calldata: vec![amount],
}])
.send()
.await
.unwrap();

trace!("Deposit result: {:?}", result);
Ok(())
}

pub async fn balance(&self, registry_address: FieldElement) -> Result<U256, Box<dyn Error>> {
let account_address = self.account.address();
let call_result = self
.get_provider()
.call(
FunctionCall {
contract_address: registry_address,
entry_point_selector: selector!("balance"),
calldata: vec![account_address],
},
BlockId::Tag(BlockTag::Latest),
)
.await
.expect("failed to call contract");

let low: u128 = call_result[0].try_into().unwrap();
let high: u128 = call_result[1].try_into().unwrap();
let call_result = U256::from(high << 128 | low);
trace!("Balance result: {:?}", call_result);

Ok(call_result)
}
}
51 changes: 1 addition & 50 deletions crates/peer/src/registry.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
use async_stream::try_stream;
use futures::stream::Stream;
use starknet::{
accounts::{Account, Call, SingleOwnerAccount},
core::{
types::{BlockId, EmittedEvent, EventFilter, FieldElement},
utils::get_selector_from_name,
},
core::types::{BlockId, EmittedEvent, EventFilter, FieldElement},
providers::Provider,
signers::Signer,
};
use std::{error::Error, pin::Pin};
use tracing::trace;
Expand Down Expand Up @@ -78,48 +73,4 @@ where
};
Box::pin(stream)
}

pub async fn deposit<S>(
&self,
amount: FieldElement,
account: SingleOwnerAccount<P, S>,
) -> Result<(), Box<dyn Error>>
where
S: Signer + Sync + Send + 'static,
{
let result = account
.execute(vec![Call {
to: self.registry_address,
selector: get_selector_from_name("deposit").unwrap(),
calldata: vec![amount],
}])
.send()
.await
.unwrap();

trace!("Deposit result: {:?}", result);
Ok(())
}

pub async fn balance<S>(
&self,
target: FieldElement,
account: SingleOwnerAccount<P, S>,
) -> Result<(), Box<dyn Error>>
where
S: Signer + Sync + Send + 'static,
{
let result = account
.execute(vec![Call {
to: self.registry_address,
selector: get_selector_from_name("balance").unwrap(),
calldata: vec![target],
}])
.send()
.await
.unwrap();

trace!("Balance result: {:?}", result);
Ok(())
}
}

0 comments on commit a962cd7

Please sign in to comment.