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

Waylon/time oracle #409

Merged
merged 22 commits into from
Aug 3, 2023
Merged
Show file tree
Hide file tree
Changes from 12 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
6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
[workspace]
# List of crates included in this workspace
members = [
"core",
"arbiter-core",
]

# Package configuration
Expand All @@ -21,7 +21,7 @@ path = "bin/main.rs"
# Dependency configuration
[dependencies]
# Local dependencies
core = { path = "core" }
arbiter-core = { path = "arbiter-core" }

# External dependencies
clap = { version = "4.3.0", features = ["derive"] }
Expand All @@ -36,6 +36,8 @@ bytes = "1.4.0"

# Simulation dependencies
quote = "1.0.28"
statrs = "0.16.0"
RustQuant = "0.0.23"

# Development dependencies
[dev-dependencies]
Expand Down
7 changes: 5 additions & 2 deletions core/Cargo.toml → arbiter-core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
# Package configuration
[package]
name = "core"
name = "arbiter-core"
version = "0.3.0"
edition = "2021"

# Dependency configuration
[dependencies]
# For execution
dashmap = "5.5.0"
0xJepsen marked this conversation as resolved.
Show resolved Hide resolved
bytes = "1.4.0"
revm = "3.3.0"
statrs = "0.16.0"

# For handling events
crossbeam-channel = "0.5.8"
Expand All @@ -17,6 +19,7 @@ crossbeam-channel = "0.5.8"
rand = "0.8.5"
rand_chacha = "0.3.1"
rand_distr = "0.4.3"
RustQuant = "*"

# For void middleware
async-trait = "0.1.68"
Expand All @@ -30,7 +33,7 @@ thiserror = "1.0.30"
# url = "2.2.2"

# Workspace dependencies
ethers = { git = "https://github.com/Autoparallel/ethers-rs.git"}
ethers = { git = "https://github.com/primitivefinance/ethers-rs.git"}
0xJepsen marked this conversation as resolved.
Show resolved Hide resolved
# ethers-middleware = { version = "2.0.4" }
serde = { version = "1.0.163", features= ["derive"]}
serde_json = { version = "1.0.96" }
Expand Down
File renamed without changes.
File renamed without changes.
7 changes: 4 additions & 3 deletions core/src/agent.rs → arbiter-core/src/agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ impl<M: Middleware> std::fmt::Debug for Agent<M> {
}

impl Agent<RevmMiddleware> {
pub(crate) fn new_simulation_agent(name: String, connection: Connection) -> Self {
pub(crate) fn new_simulation_agent(name: String, connection: &Connection) -> Self {
Self {
name: name.clone(),
client: Arc::new(RevmMiddleware::new(connection, name)),
client: Arc::new(RevmMiddleware::new(connection.clone(), name)),
behaviors: vec![],
}
}
Expand Down Expand Up @@ -62,9 +62,10 @@ pub(crate) mod tests {
pub(crate) const TEST_AGENT_NAME: &str = "test_agent";
pub(crate) const TEST_BEHAVIOR_DATA: &str = "test_behavior_data";

use super::*;
use ethers::providers::{MockProvider, ProviderError};

use super::*;

#[derive(Debug)]
pub(crate) struct TestMiddleware {}

Expand Down
File renamed without changes.
83 changes: 65 additions & 18 deletions core/src/environment.rs → arbiter-core/src/environment.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,45 @@
#![warn(missing_docs)]
#![warn(unsafe_code)]

use std::{
fmt::Debug,
sync::{
atomic::{AtomicUsize, Ordering},
Arc, Mutex,
},
thread,
collections::HashMap,
};

use crossbeam_channel::{unbounded, Receiver, Sender};
use ethers::core::types::U64;
use revm::{
db::{CacheDB, EmptyDB},
primitives::{ExecutionResult, Log, TxEnv, U256},
EVM,
};
use std::{
fmt::Debug,
sync::{Arc, Mutex},
thread,
};

use crate::utils::revm_logs_to_ethers_logs;
use crate::{agent::Agent, middleware::RevmMiddleware};
use crate::{
agent::Agent,
math::stochastic_process::poisson_process,
middleware::RevmMiddleware,
utils::{convert_uint_to_u64, revm_logs_to_ethers_logs},
};

/// Type Aliases for the event channel.
pub(crate) type ToTransact = bool;
pub(crate) type ExecutionSender = Sender<ExecutionResult>;
pub(crate) type ExecutionSender = Sender<RevmResult>;
pub(crate) type TxEnvSender = Sender<(ToTransact, TxEnv, ExecutionSender)>;
pub(crate) type TxEnvReceiver = Receiver<(ToTransact, TxEnv, ExecutionSender)>;

/// Result struct for the [`Environment`]. that wraps the [`ExecutionResult`] and the block number.
#[derive(Debug, Clone)]
pub struct RevmResult {
pub(crate) result: ExecutionResult,
pub(crate) block_number: U64,
}

/// State enum for the [`Environment`].
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
pub enum State {
/// The [`Environment`] is currently running.
Expand All @@ -32,63 +50,84 @@ pub enum State {
Stopped,
}

/// The environment struct.
pub struct Environment {
/// label for the environment
pub label: String,
pub(crate) state: State,
pub(crate) evm: EVM<CacheDB<EmptyDB>>,
/// Connection to the environment
pub connection: Connection,
/// Clients (Agents) in the environment
pub clients: Vec<Arc<Agent<RevmMiddleware>>>,
// pub deployed_contracts: HashMap<String, Contract<RevmMiddleware>>,
pub clients: HashMap<String, Agent<RevmMiddleware>>,
0xJepsen marked this conversation as resolved.
Show resolved Hide resolved
/// expected events per block
pub lambda: f64,
}

/// Connection struct for the [`Environment`].
#[derive(Debug, Clone)]
pub struct Connection {
pub(crate) tx_sender: TxEnvSender,
tx_receiver: TxEnvReceiver,
pub(crate) event_broadcaster: Arc<Mutex<EventBroadcaster>>,
/// expected events per block
pub tx_per_block: Arc<AtomicUsize>,
}

impl Environment {
/// Create a new [`Environment`].
pub(crate) fn new(label: String) -> Self {
let mut evm = EVM::new();
let db = CacheDB::new(EmptyDB {});
evm.database(db);
evm.env.cfg.limit_contract_code_size = Some(0x100000); // This is a large contract size limit, beware!
evm.env.block.gas_limit = U256::MAX;
let transaction_channel = unbounded::<(ToTransact, TxEnv, Sender<ExecutionResult>)>();
let transaction_channel = unbounded::<(ToTransact, TxEnv, Sender<RevmResult>)>();
let connection = Connection {
tx_sender: transaction_channel.0,
tx_receiver: transaction_channel.1,
event_broadcaster: Arc::new(Mutex::new(EventBroadcaster::new())),
tx_per_block: Arc::new(AtomicUsize::new(0)),
};
Self {
label,
state: State::Stopped,
evm,
connection,
clients: vec![],
clients: HashMap::new(),
lambda: 0.0,
}
}
// TODO: We need to make this the way to add agents to the environment.
// in `agent.rs` we have `new_simulation_agent` which should probably just be called from this function instead.
// OR agents can be created (without a connection?) and then added to the environment where they will gain a connection?
pub fn add_agent(&mut self, agent: Agent<RevmMiddleware>) {
self.clients.push(Arc::new(agent));
/// Set the expected events per block
pub(crate) fn configure_lambda(&mut self, lambda: f64) {
0xJepsen marked this conversation as resolved.
Show resolved Hide resolved
self.lambda = lambda;
}

/// Creates a new [`Agent<RevmMiddleware`] with the given label.
pub(crate) fn add_agent(&mut self, name: String) {
let agent = Agent::new_simulation_agent(name.clone(), &self.connection);
self.clients.insert(name, agent);
}

// TODO: Run should now run the agents as well as the evm.
pub(crate) fn run(&mut self) {
let tx_receiver = self.connection.tx_receiver.clone();
let mut evm = self.evm.clone();
let event_broadcaster = self.connection.event_broadcaster.clone();
let counter = Arc::clone(&self.connection.tx_per_block);
let expected_occurance = poisson_process(self.lambda, 1).unwrap();
self.state = State::Running;

//give all agents their own thread and let them start watching for their evnts
thread::spawn(move || {
while let Ok((to_transact, tx, sender)) = tx_receiver.recv() {
// Execute the transaction, echo the logs to all agents, and report the execution result to the agent who made the transaction.
if counter.load(Ordering::Relaxed) >= expected_occurance[0] as usize {
evm.env.block.number += U256::from(1);
counter.store(0, Ordering::Relaxed);
}
evm.env.tx = tx;
counter.fetch_add(1, Ordering::Relaxed);
0xJepsen marked this conversation as resolved.
Show resolved Hide resolved
if to_transact {
let execution_result = match evm.transact_commit() {
Ok(val) => val,
Expand All @@ -99,14 +138,22 @@ impl Environment {
.lock()
.unwrap()
.broadcast(execution_result.logs());
let execution_result = RevmResult {
result: execution_result,
block_number: convert_uint_to_u64(evm.env.block.number).unwrap(),
};
sender.send(execution_result).unwrap();
} else {
let execution_result = match evm.transact() {
Ok(val) => val,
// URGENT: change this to a custom error
Err(_) => panic!("failed"),
};
sender.send(execution_result.result).unwrap();
let result_and_block = RevmResult {
result: execution_result.result,
block_number: convert_uint_to_u64(evm.env.block.number).unwrap(),
};
sender.send(result_and_block).unwrap();
}
}
});
Expand Down
1 change: 1 addition & 0 deletions core/src/lib.rs → arbiter-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

pub mod agent;
pub mod bindings;
/// Module for managing the environment.
0xJepsen marked this conversation as resolved.
Show resolved Hide resolved
pub mod environment;
pub mod manager;
pub mod math;
Expand Down
26 changes: 25 additions & 1 deletion core/src/manager.rs → arbiter-core/src/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@

use std::collections::HashMap;

use crate::environment::{Environment, State};
use anyhow::{anyhow, Result};

use crate::environment::{Environment, State};

/// Manages simulations.
#[derive(Default)]
pub struct SimulationManager {
/// The list of [`SimulationEnvironment`] that the simulation manager controls.
pub environments: HashMap<String, Environment>,
Expand All @@ -34,6 +36,28 @@ impl SimulationManager {
Ok(())
}

/// Configure the lambda for an environment.
pub fn configure_lambda(&mut self, lambda: f64, environment_label: String) -> Result<()> {
0xJepsen marked this conversation as resolved.
Show resolved Hide resolved
match self.environments.get_mut(&environment_label) {
Some(environment) => {
environment.configure_lambda(lambda);
Ok(())
}
None => Err(anyhow!("Environment does not exist.")),
}
}

/// adds an agent to an environment
pub fn add_agent(&mut self, agent_name: String, environment_label: String) -> Result<()> {
match self.environments.get_mut(&environment_label) {
Some(environment) => {
environment.add_agent(agent_name);
Ok(())
}
None => Err(anyhow!("Environment does not exist.")),
}
}

/// Runs an environment that is in the [`SimulationManager`]'s list.
pub fn run_environment(&mut self, environment_label: String) -> Result<()> {
match self.environments.get_mut(&environment_label) {
Expand Down
1 change: 1 addition & 0 deletions core/src/math/mod.rs → arbiter-core/src/math/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use ethers::types::U256;

/// Stochastic process module.
0xJepsen marked this conversation as resolved.
Show resolved Hide resolved
pub mod stochastic_process;

/// Converts a float to a WAD fixed point prepared U256 number.
Expand Down
Loading
Loading