This library implements the time boost ordering policy for blockchain transactions in Rust.
The protocol is described by a research paper titled "Buying Time: Latency Racing vs. Bidding for Transaction Ordering" created by researchers at @OffchainLabs, Akaki Mamageishvili, Mahimna Kelkar, Ed Felten, and Jan Christoph Schlegel from University of London. All ideas implemented in this crate are a result of the aforementioned research.
Time Boost is an approach for transaction fair ordering that accounts timestamps and bids to create a score that can be used to sort transactions for rollup sequencers. It supports low-latency finality, similar to first-come, first-serve, but is more fair towards users. With time boost, bids can help buy time in a final ordering, but only up to a constant factor G
, defined in milliseconds.
This library contains Rust code that defines an asynchronous TimeBoostService
that can take in transactions via an input channel, and output a final ordered list continuously by applying the protocol internally. This implementation is a "discrete" version of the time boost protocol because it operates in rounds of time G
. Here's how it works:
T
T+G
, where G
is a constant defined in milliseconds, all txs are in the priority queue are released and their timestamps are modified to be the time they are emitted in the output feedT = T_now
until the next roundCredits to Ed Felten for the idea.
Rust stable version 1.71.1
```rust use timeboost_rs::{TimeBoostService, BoostableTx}; use tokio::sync::broadcast;
async fn main() { let (txoutputfeed, mut rx) = broadcast::channel(100); let mut service = TimeBoostService::new(txoutputfeed);
// Obtain a channel handle to send txs to the TimeBoostService.
let sender = service.sender();
// Spawn a dedicated thread for the time boost service.
std::thread::spawn(move || service.run());
let mut txs = vec![
BoostableTx::new(0 /* id */, 1 /* bid */, 100 /* unix timestamp millis */),
BoostableTx::new(1 /* id */, 100 /* bid */, 101 /* unix timestamp millis */),
];
// Send the txs to the time boost service.
for tx in txs.iter() {
sender.send(tx.clone()).unwrap();
}
// Await receipt of both txs from the timeboost service's output feed.
let mut got_txs = vec![];
for _ in 0..2 {
let tx = rx.recv().await.unwrap();
got_txs.push(tx);
}
// Assert we received 2 txs from the output feed.
assert_eq!(txs.len(), 2);
// Assert the output is the same as the reversed input, as
// the highest bid txs will be released first.
txs.reverse();
let want = txs.into_iter().map(|tx| tx.id).collect::<Vec<_>>();
let got = got_txs.into_iter().map(|tx| tx.id).collect::<Vec<_>>();
assert_eq!(want, got);
} ```
Licensed under either of Apache License, Version 2.0 or MIT license at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this repository by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.