Skip to content

Commit a962cd7

Browse files
committed
fix: contract call through account, impl: reward
1 parent f6e6f2b commit a962cd7

File tree

13 files changed

+104
-99
lines changed

13 files changed

+104
-99
lines changed

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ async-stream = "0.3.5"
2828
bincode = "1.3"
2929
cairo-proof-parser = { git = "https://github.com/Okm165/cairo-proof-parser", rev = "97a04bbee07330311b38d6f4cecfed3acb237626" }
3030
cairo-vm = { git = "https://github.com/lambdaclass/cairo-vm.git" }
31+
crypto-bigint = { version = "0.5.3", features = ["serde"] }
3132
futures = "0.3.30"
3233
futures-core = "0.3.30"
3334
futures-util = "0.3.30"

crates/common/Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ license-file.workspace = true
99

1010
[dependencies]
1111
cairo-vm.workspace = true
12+
crypto-bigint.workspace = true
1213
futures.workspace = true
1314
hex.workspace = true
1415
libp2p.workspace = true
@@ -22,4 +23,4 @@ starknet.workspace = true
2223
strum.workspace = true
2324
tempfile.workspace = true
2425
thiserror.workspace = true
25-
tokio.workspace = true
26+
tokio.workspace = true

crates/common/src/job.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::hash;
22
use cairo_vm::vm::runners::cairo_pie::CairoPie;
3+
use crypto_bigint::U256;
34
use serde::{Deserialize, Serialize};
45
use starknet::signers::{SigningKey, VerifyingKey};
56
use starknet_crypto::{poseidon_hash_many, FieldElement, Signature};
@@ -44,22 +45,20 @@ impl Job {
4445

4546
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
4647
pub struct JobData {
47-
pub reward: u64,
48+
pub reward: U256,
4849
pub num_of_steps: u64,
4950
#[serde(with = "chunk_felt_array")]
5051
pub cairo_pie_compressed: Vec<u8>,
5152
pub registry_address: FieldElement,
5253
}
5354

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

6564
fn decompress_cairo_pie(cairo_pie_compressed: &[u8]) -> CairoPie {

crates/common/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ pub mod job_witness;
66
pub mod layout;
77
pub mod macros;
88
pub mod network;
9-
pub mod node_account;
109
pub mod process;
1110
pub mod topic;
1211

crates/compiler/src/cairo_compiler/mod.rs

+14-17
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,8 @@ use async_process::Stdio;
33
use futures::Future;
44
use rand::{thread_rng, Rng};
55
use serde_json::json;
6-
use sharp_p2p_common::job::JobData;
76
use sharp_p2p_common::layout::Layout;
8-
use sharp_p2p_common::{job::Job, process::Process};
9-
use starknet::signers::SigningKey;
10-
use starknet_crypto::FieldElement;
7+
use sharp_p2p_common::process::Process;
118
use std::io::Write;
129
use std::path::PathBuf;
1310
use std::{io::Read, pin::Pin};
@@ -17,25 +14,28 @@ use tracing::debug;
1714

1815
pub mod tests;
1916

20-
pub struct CairoCompiler<'identity> {
21-
signing_key: &'identity SigningKey,
22-
registry_contract: FieldElement,
17+
pub struct CairoCompiler {}
18+
19+
impl CairoCompiler {
20+
pub fn new() -> Self {
21+
Self {}
22+
}
2323
}
2424

25-
impl<'identity> CairoCompiler<'identity> {
26-
pub fn new(signing_key: &'identity SigningKey, registry_contract: FieldElement) -> Self {
27-
Self { signing_key, registry_contract }
25+
impl Default for CairoCompiler {
26+
fn default() -> Self {
27+
Self::new()
2828
}
2929
}
3030

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

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

121-
Ok(Job::try_from_job_data(
122-
JobData::new(0, cairo_pie_compressed, self.registry_contract),
123-
self.signing_key,
124-
))
121+
Ok(cairo_pie_compressed)
125122
});
126123

127124
Ok(Process::new(future, terminate_tx))

crates/compiler/src/cairo_compiler/tests/single_job.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,20 @@ use crate::{
33
traits::CompilerController,
44
};
55
use starknet::signers::SigningKey;
6-
use starknet_crypto::FieldElement;
76

87
#[tokio::test]
98
async fn run_single_job() {
109
let fixture = fixture();
11-
let identity = SigningKey::from_random();
12-
let compiler = CairoCompiler::new(&identity, FieldElement::ZERO);
10+
let _identity = SigningKey::from_random();
11+
let compiler = CairoCompiler::new();
1312
compiler.run(fixture.program_path, fixture.program_input_path).unwrap().await.unwrap();
1413
}
1514

1615
#[tokio::test]
1716
async fn abort_single_jobs() {
1817
let fixture = fixture();
19-
let identity = SigningKey::from_random();
20-
let compiler = CairoCompiler::new(&identity, FieldElement::ZERO);
18+
let _identity = SigningKey::from_random();
19+
let compiler = CairoCompiler::new();
2120
let job = compiler.run(fixture.program_path, fixture.program_input_path).unwrap();
2221
job.abort().await.unwrap();
2322
job.await.unwrap_err();

crates/compiler/src/traits.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
use crate::errors::CompilerControllerError;
2-
use sharp_p2p_common::{job::Job, process::Process};
2+
use sharp_p2p_common::process::Process;
33
use std::path::PathBuf;
44

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

1312
pub trait CompilerController {
1413
fn run(
1514
&self,
1615
program_path: PathBuf,
1716
program_input_path: PathBuf,
18-
) -> Result<Process<Result<Job, CompilerControllerError>>, CompilerControllerError>;
17+
) -> Result<Process<Result<Vec<u8>, CompilerControllerError>>, CompilerControllerError>;
1918
}

crates/delegator/src/main.rs

+17-6
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@ use futures::{stream::FuturesUnordered, StreamExt};
44
use libp2p::gossipsub::Event;
55
use sharp_p2p_common::{
66
hash,
7-
job::Job,
7+
job::{Job, JobData},
88
network::Network,
9-
node_account::NodeAccount,
109
process::Process,
1110
topic::{gossipsub_ident_topic, Topic},
1211
};
@@ -15,7 +14,7 @@ use sharp_p2p_compiler::{
1514
errors::CompilerControllerError,
1615
traits::CompilerController,
1716
};
18-
use sharp_p2p_peer::{registry::RegistryHandler, swarm::SwarmRunner};
17+
use sharp_p2p_peer::{node_account::NodeAccount, registry::RegistryHandler, swarm::SwarmRunner};
1918
use starknet::providers::{jsonrpc::HttpTransport, JsonRpcClient, Url};
2019
use std::hash::{DefaultHasher, Hash, Hasher};
2120
use tokio::{
@@ -60,13 +59,15 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
6059
let mut message_stream = swarm_runner.run(new_job_topic, send_topic_rx);
6160
let mut event_stream = registry_handler.subscribe_events(vec!["0x0".to_string()]);
6261

63-
let compiler = CairoCompiler::new(node_account.get_signing_key(), registry_address);
62+
let compiler = CairoCompiler::new();
6463

6564
let mut compiler_scheduler =
66-
FuturesUnordered::<Process<'_, Result<Job, CompilerControllerError>>>::new();
65+
FuturesUnordered::<Process<'_, Result<Vec<u8>, CompilerControllerError>>>::new();
6766

6867
// Read cairo program path from stdin
6968
let mut stdin = BufReader::new(stdin()).lines();
69+
// TODO: Accept dynamic tip
70+
let tip = 10;
7071

7172
loop {
7273
tokio::select! {
@@ -104,7 +105,17 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
104105
Some(Ok(event_vec)) = event_stream.next() => {
105106
debug!("{:?}", event_vec);
106107
},
107-
Some(Ok(job)) = compiler_scheduler.next() => {
108+
Some(Ok(cairo_pie_compressed)) = compiler_scheduler.next() => {
109+
let job_data = JobData::new(tip, cairo_pie_compressed,registry_address);
110+
let expected_reward = job_data.reward;
111+
let staked_amount = node_account.balance(registry_address).await?;
112+
// TODO: handle error better way
113+
if staked_amount < expected_reward{
114+
return Err("Staked amount is less than expected reward".into());
115+
}
116+
let job = Job::try_from_job_data(job_data, node_account.get_signing_key());
117+
// info!("Job: {:?}", job.job_data.reward);
118+
// info!("Job: {:?}", job.job_data.num_of_steps);
108119
let serialized_job = serde_json::to_string(&job).unwrap();
109120
send_topic_tx.send(serialized_job.into()).await?;
110121
info!("Sent a new job: {}", hash!(&job));

crates/executor/src/main.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,10 @@ use sharp_p2p_common::{
99
job_trace::JobTrace,
1010
job_witness::JobWitness,
1111
network::Network,
12-
node_account::NodeAccount,
1312
process::Process,
1413
topic::{gossipsub_ident_topic, Topic},
1514
};
16-
use sharp_p2p_peer::{registry::RegistryHandler, swarm::SwarmRunner};
15+
use sharp_p2p_peer::{node_account::NodeAccount, registry::RegistryHandler, swarm::SwarmRunner};
1716
use sharp_p2p_prover::{
1817
errors::ProverControllerError, stone_prover::StoneProver, traits::ProverController,
1918
};

crates/peer/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ license-file.workspace = true
99

1010
[dependencies]
1111
async-stream.workspace = true
12+
crypto-bigint.workspace = true
1213
futures.workspace = true
1314
libp2p.workspace = true
1415
starknet.workspace = true

crates/peer/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
pub mod node_account;
12
pub mod registry;
23
pub mod swarm;

crates/common/src/node_account.rs renamed to crates/peer/src/node_account.rs

+51-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
1+
use std::error::Error;
2+
3+
use crypto_bigint::U256;
4+
use sharp_p2p_common::network::Network;
15
use starknet::{
2-
accounts::{ConnectedAccount, ExecutionEncoding, SingleOwnerAccount},
3-
core::types::FieldElement,
6+
accounts::{Account, Call, ConnectedAccount, ExecutionEncoding, SingleOwnerAccount},
7+
core::types::{BlockId, BlockTag, FieldElement, FunctionCall},
8+
macros::selector,
49
providers::Provider,
510
signers::{LocalWallet, SigningKey, VerifyingKey},
611
};
7-
8-
use crate::network::Network;
12+
use tracing::trace;
913

1014
pub struct NodeAccount<P>
1115
where
@@ -62,4 +66,47 @@ where
6266
pub fn get_verifying_key(&self) -> VerifyingKey {
6367
self.signing_key.verifying_key()
6468
}
69+
70+
pub async fn deposit(
71+
&self,
72+
amount: FieldElement,
73+
registry_address: FieldElement,
74+
) -> Result<(), Box<dyn Error>> {
75+
let result = self
76+
.account
77+
.execute(vec![Call {
78+
to: registry_address,
79+
selector: selector!("deposit"),
80+
calldata: vec![amount],
81+
}])
82+
.send()
83+
.await
84+
.unwrap();
85+
86+
trace!("Deposit result: {:?}", result);
87+
Ok(())
88+
}
89+
90+
pub async fn balance(&self, registry_address: FieldElement) -> Result<U256, Box<dyn Error>> {
91+
let account_address = self.account.address();
92+
let call_result = self
93+
.get_provider()
94+
.call(
95+
FunctionCall {
96+
contract_address: registry_address,
97+
entry_point_selector: selector!("balance"),
98+
calldata: vec![account_address],
99+
},
100+
BlockId::Tag(BlockTag::Latest),
101+
)
102+
.await
103+
.expect("failed to call contract");
104+
105+
let low: u128 = call_result[0].try_into().unwrap();
106+
let high: u128 = call_result[1].try_into().unwrap();
107+
let call_result = U256::from(high << 128 | low);
108+
trace!("Balance result: {:?}", call_result);
109+
110+
Ok(call_result)
111+
}
65112
}

crates/peer/src/registry.rs

+1-50
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
11
use async_stream::try_stream;
22
use futures::stream::Stream;
33
use starknet::{
4-
accounts::{Account, Call, SingleOwnerAccount},
5-
core::{
6-
types::{BlockId, EmittedEvent, EventFilter, FieldElement},
7-
utils::get_selector_from_name,
8-
},
4+
core::types::{BlockId, EmittedEvent, EventFilter, FieldElement},
95
providers::Provider,
10-
signers::Signer,
116
};
127
use std::{error::Error, pin::Pin};
138
use tracing::trace;
@@ -78,48 +73,4 @@ where
7873
};
7974
Box::pin(stream)
8075
}
81-
82-
pub async fn deposit<S>(
83-
&self,
84-
amount: FieldElement,
85-
account: SingleOwnerAccount<P, S>,
86-
) -> Result<(), Box<dyn Error>>
87-
where
88-
S: Signer + Sync + Send + 'static,
89-
{
90-
let result = account
91-
.execute(vec![Call {
92-
to: self.registry_address,
93-
selector: get_selector_from_name("deposit").unwrap(),
94-
calldata: vec![amount],
95-
}])
96-
.send()
97-
.await
98-
.unwrap();
99-
100-
trace!("Deposit result: {:?}", result);
101-
Ok(())
102-
}
103-
104-
pub async fn balance<S>(
105-
&self,
106-
target: FieldElement,
107-
account: SingleOwnerAccount<P, S>,
108-
) -> Result<(), Box<dyn Error>>
109-
where
110-
S: Signer + Sync + Send + 'static,
111-
{
112-
let result = account
113-
.execute(vec![Call {
114-
to: self.registry_address,
115-
selector: get_selector_from_name("balance").unwrap(),
116-
calldata: vec![target],
117-
}])
118-
.send()
119-
.await
120-
.unwrap();
121-
122-
trace!("Balance result: {:?}", result);
123-
Ok(())
124-
}
12576
}

0 commit comments

Comments
 (0)