Skip to content

Commit

Permalink
use bidder config when computing value to bid
Browse files Browse the repository at this point in the history
  • Loading branch information
ralexstokes committed Apr 29, 2024
1 parent fbcdf06 commit 33db163
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 48 deletions.
7 changes: 5 additions & 2 deletions example.config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,11 @@ execution_mnemonic = "abandon abandon abandon abandon abandon abandon abandon ab
[builder.bidder]
# number of milliseconds to submit bids ahead of the target slot
bidding_deadline_ms = 1000
# amount of value to bid as a fraction of the payload's revenue
# [optional] amount of value to bid as a fraction of the payload's revenue
# if missing, defaults to 1.0 (100%)
# validation: should be between [0, 1] inclusive.
bid_percent = 0.9
# amount to add to the bid on top of the payload's revenue,
# [optional] amount to add to the bid on top of the payload's revenue,
# if missing, defaults to 0 wei
# currently sourced from the builder's wallet authoring the payment transaction
subsidy_wei = "0x0000000000000000000000000000000000000000000000000000000000000001"
29 changes: 15 additions & 14 deletions mev-build-rs/src/auctioneer/service.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
auctioneer::auction_schedule::{AuctionSchedule, Proposals, Proposer, RelaySet},
bidder::{BidStatus, Message as BidderMessage},
bidder::Message as BidderMessage,
payload::attributes::{BuilderPayloadBuilderAttributes, ProposalAttributes},
service::ClockMessage,
utils::compat::{to_bytes20, to_bytes32, to_execution_payload},
Expand Down Expand Up @@ -101,7 +101,7 @@ pub struct Service<
// TODO consolidate this somewhere...
genesis_time: u64,
bidder: Sender<BidderMessage>,
bid_dispatch: Receiver<BidStatus>,
bid_dispatch: Receiver<BidderMessage>,

auction_schedule: AuctionSchedule,
open_auctions: HashMap<PayloadId, Arc<AuctionContext>>,
Expand All @@ -118,7 +118,7 @@ impl<
clock: broadcast::Receiver<ClockMessage>,
builder: PayloadBuilderHandle<Engine>,
bidder: Sender<BidderMessage>,
bid_dispatch: Receiver<BidStatus>,
bid_dispatch: Receiver<BidderMessage>,
mut config: Config,
context: Arc<Context>,
genesis_time: u64,
Expand Down Expand Up @@ -236,18 +236,19 @@ impl<
}
}

async fn process_bid_update(&mut self, message: BidStatus) {
let BidStatus::Dispatch(payload_id, _keep_alive) = message;
// TODO: may want to keep payload job running...
// NOTE: move back to builder interface over payload builder, that can also do this on its
// own thread?
if let Some(payload) = self.payload_store.resolve(payload_id).await {
match payload {
Ok(payload) => self.submit_payload(payload).await,
Err(err) => warn!(%err, "payload resolution failed"),
async fn process_bid_update(&mut self, message: BidderMessage) {
if let BidderMessage::Dispatch(payload_id, _keep_alive) = message {
// TODO: may want to keep payload job running...
// NOTE: move back to builder interface over payload builder, that can also do this on
// its own thread?
if let Some(payload) = self.payload_store.resolve(payload_id).await {
match payload {
Ok(payload) => self.submit_payload(payload).await,
Err(err) => warn!(%err, "payload resolution failed"),
}
} else {
warn!(%payload_id, "no payload could be retrieved from payload store for bid")
}
} else {
warn!(%payload_id, "no payload could be retrieved from payload store for bid")
}
}

Expand Down
4 changes: 3 additions & 1 deletion mev-build-rs/src/bidder/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
mod service;
pub mod strategies;

pub use service::{BidStatus, Config, KeepAlive, Message, Service};
pub use strategies::Config;

pub use service::{BidStatus, KeepAlive, Message, Service};
51 changes: 26 additions & 25 deletions mev-build-rs/src/bidder/service.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
use crate::{auctioneer::AuctionContext, bidder::strategies::DeadlineBidder};
use reth::{payload::PayloadId, primitives::U256, tasks::TaskExecutor};
use serde::Deserialize;
use std::{sync::Arc, time::Duration};
use crate::{
auctioneer::AuctionContext,
bidder::{strategies::DeadlineBidder, Config},
};
use reth::{
api::PayloadBuilderAttributes, payload::PayloadId, primitives::U256, tasks::TaskExecutor,
};
use std::sync::Arc;
use tokio::sync::mpsc::{Receiver, Sender};

pub enum Message {
NewAuction(Arc<AuctionContext>),
Dispatch(PayloadId, KeepAlive),
}

#[derive(Debug)]
Expand All @@ -14,32 +19,20 @@ pub enum KeepAlive {
}

pub enum BidStatus {
Dispatch(PayloadId, KeepAlive),
}

#[derive(Deserialize, Debug, Default, Clone)]
pub struct Config {
// amount in milliseconds
pub bidding_deadline_ms: u64,
// amount to bid as a fraction of the block's value
// TODO: use to price bid
pub bid_percent: Option<f64>,
// amount to add from the builder's wallet as a subsidy to the auction bid
// TODO: use to adjust bid
pub subsidy_wei: Option<U256>,
Submit { value: U256, keep_alive: KeepAlive },
}

pub struct Service {
auctioneer: Receiver<Message>,
bid_dispatch: Sender<BidStatus>,
bid_dispatch: Sender<Message>,
executor: TaskExecutor,
config: Config,
}

impl Service {
pub fn new(
auctioneer: Receiver<Message>,
bid_dispatch: Sender<BidStatus>,
bid_dispatch: Sender<Message>,
executor: TaskExecutor,
config: Config,
) -> Self {
Expand All @@ -49,17 +42,25 @@ impl Service {
fn start_bid(&mut self, auction: Arc<AuctionContext>) {
let dispatcher = self.bid_dispatch.clone();
// TODO: make strategies configurable...
let deadline = Duration::from_millis(self.config.bidding_deadline_ms);
let mut strategy = DeadlineBidder::new(deadline);
let mut strategy = DeadlineBidder::new(&self.config);
self.executor.spawn_blocking(async move {
let bid_status = strategy.run(&auction).await;
dispatcher.send(bid_status).await.expect("can send");
// TODO get current fees from builder
let fees = U256::from(100);
let BidStatus::Submit { value: _value, keep_alive } =
strategy.run(&auction, fees).await;
// TODO send value to builder

dispatcher
.send(Message::Dispatch(auction.attributes.payload_id(), keep_alive))
.await
.expect("can send");
});
}

async fn dispatch(&mut self, message: Message) {
let Message::NewAuction(auction) = message;
self.start_bid(auction);
if let Message::NewAuction(auction) = message {
self.start_bid(auction);
}
}

pub async fn spawn(mut self) {
Expand Down
38 changes: 33 additions & 5 deletions mev-build-rs/src/bidder/strategies/deadline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,56 @@ use crate::{
bidder::{BidStatus, KeepAlive},
};
use ethereum_consensus::clock::duration_until;
use reth::api::PayloadBuilderAttributes;
use reth::{api::PayloadBuilderAttributes, primitives::U256};
use serde::Deserialize;
use std::time::Duration;
use tokio::time::sleep;

#[derive(Deserialize, Debug, Default, Clone)]
pub struct Config {
// amount in milliseconds
pub bidding_deadline_ms: u64,
// amount to bid as a fraction of the block's value
// if missing, default to 100%
// TODO: use to price bid
pub bid_percent: Option<f64>,
// amount to add from the builder's wallet as a subsidy to the auction bid
// TODO: use to adjust bid
pub subsidy_wei: Option<U256>,
}

/// `DeadlineBidder` submits the best payload *once* at the `deadline`
/// expressed as a `Duration` *before* the start of the build's target slot.
///
/// For example, if the `deadline` is 1 second, then the bidder will return
/// a value to bid one second before the start of the build's target slot.
pub struct DeadlineBidder {
deadline: Duration,
bid_percent: f64,
subsidy_wei: U256,
}

impl DeadlineBidder {
pub fn new(deadline: Duration) -> Self {
Self { deadline }
pub fn new(config: &Config) -> Self {
let deadline = Duration::from_millis(config.bidding_deadline_ms);
Self {
deadline,
bid_percent: config.bid_percent.unwrap_or(1.0).clamp(0.0, 1.0),
subsidy_wei: config.subsidy_wei.unwrap_or(U256::ZERO),
}
}

fn compute_value(&self, current_revenue: U256) -> U256 {
let mut value = current_revenue * U256::from(self.bid_percent * 100.0) / U256::from(100);
value += self.subsidy_wei;
value
}

pub async fn run(&mut self, auction: &AuctionContext) -> BidStatus {
pub async fn run(&mut self, auction: &AuctionContext, current_revenue: U256) -> BidStatus {
let value = self.compute_value(current_revenue);
let target = duration_until(auction.attributes.timestamp());
let duration = target.checked_sub(self.deadline).unwrap_or_default();
sleep(duration).await;
BidStatus::Dispatch(auction.attributes.payload_id(), KeepAlive::No)
BidStatus::Submit { value, keep_alive: KeepAlive::No }
}
}
2 changes: 1 addition & 1 deletion mev-build-rs/src/bidder/strategies/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
mod deadline;

pub use deadline::DeadlineBidder;
pub use deadline::{Config, DeadlineBidder};

0 comments on commit 33db163

Please sign in to comment.