Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
GoodDaisy authored Oct 27, 2023
2 parents d6e2363 + 1cccb9f commit 593b260
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 34 deletions.
7 changes: 4 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions bin/rundler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,5 @@ tokio-rustls = "0.24.1"
tokio-util = "0.7.8"
tracing.workspace = true
tracing-appender = "0.2.2"
tracing-log = "0.1.3"
tracing-subscriber = { version = "0.3.16", features = ["env-filter", "fmt", "json"] }
4 changes: 4 additions & 0 deletions bin/rundler/src/cli/tracing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use std::io;
pub use tracing::*;
use tracing::{subscriber, subscriber::Interest, Metadata, Subscriber};
use tracing_appender::non_blocking::WorkerGuard;
use tracing_log::LogTracer;
use tracing_subscriber::{layer::SubscriberExt, EnvFilter, FmtSubscriber, Layer};

use super::LogsArgs;
Expand Down Expand Up @@ -46,6 +47,9 @@ pub fn configure_logging(config: &LogsArgs) -> anyhow::Result<WorkerGuard> {
)?;
}

// Redirect logs from external crates using `log` to the tracing subscriber
LogTracer::init()?;

Ok(guard)
}

Expand Down
81 changes: 54 additions & 27 deletions crates/builder/src/signer/aws.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use std::{sync::Arc, time::Duration};
use anyhow::Context;
use ethers::providers::Middleware;
use ethers_signers::{AwsSigner, Signer};
use rslock::{LockGuard, LockManager};
use rslock::{Lock, LockGuard, LockManager};
use rundler_utils::handle::SpawnGuard;
use rusoto_core::Region;
use rusoto_kms::KmsClient;
Expand All @@ -28,7 +28,7 @@ use super::monitor_account_balance;
#[derive(Debug)]
pub(crate) struct KmsSigner {
pub(crate) signer: AwsSigner,
_kms_guard: SpawnGuard,
_kms_guard: Option<SpawnGuard>,
_monitor_guard: SpawnGuard,
}

Expand All @@ -41,15 +41,27 @@ impl KmsSigner {
redis_uri: String,
ttl_millis: u64,
) -> anyhow::Result<Self> {
let (tx, rx) = oneshot::channel::<String>();
let kms_guard = SpawnGuard::spawn_with_guard(Self::lock_manager_loop(
redis_uri, key_ids, chain_id, ttl_millis, tx,
));
let key_id = rx.await.context("should lock key_id")?;
let client = KmsClient::new(region);
let mut kms_guard = None;
let key_id;

if key_ids.len() > 1 {
let (tx, rx) = oneshot::channel::<String>();
kms_guard = Some(SpawnGuard::spawn_with_guard(Self::lock_manager_loop(
redis_uri, key_ids, chain_id, ttl_millis, tx,
)));
key_id = rx.await.context("should lock key_id")?;
} else {
key_id = key_ids
.first()
.expect("There should be at least one kms key")
.to_owned();
};

let signer = AwsSigner::new(client, key_id, chain_id)
.await
.context("should create signer")?;

let monitor_guard = SpawnGuard::spawn_with_guard(monitor_account_balance(
signer.address(),
provider.clone(),
Expand All @@ -73,43 +85,58 @@ impl KmsSigner {

let mut lock = None;
let mut kid = None;
let mut locked_id = None;
let lock_context = key_ids
.into_iter()
.map(|id| (format!("{chain_id}:{id}"), id))
.collect::<Vec<_>>();

for (lock_id, key_id) in lock_context.iter() {
match lm.lock(lock_id.as_bytes(), ttl_millis as usize).await {
Ok(l) => {
lock = Some(l);
kid = Some(key_id.clone());
tracing::info!("locked key_id {key_id}");
break;
}
Err(e) => {
tracing::warn!("could not lock key_id {key_id}: {e:?}");
continue;
}
if let Some(l) = try_lock(&lm, lock_id, ttl_millis as usize).await {
lock = Some(l);
kid = Some(key_id.clone());
locked_id = Some(lock_id.clone());
break;
}
}
if lock.is_none() {
return;
}
let _ = locked_tx.send(kid.unwrap());

let lg = LockGuard {
let lock_id = locked_id.unwrap();
let _ = locked_tx.send(kid.unwrap());
let mut lg_opt = Some(LockGuard {
lock: lock.unwrap(),
};
});

loop {
sleep(Duration::from_millis(ttl_millis / 10)).await;
match lm.extend(&lg.lock, ttl_millis as usize).await {
Ok(_) => {
tracing::debug!("extended lock");
}
Err(e) => {
tracing::error!("could not extend lock: {e:?}");

if let Some(lg) = &lg_opt {
match lm.extend(&lg.lock, ttl_millis as usize).await {
Ok(_) => {
tracing::debug!("extended lock");
}
Err(e) => {
tracing::error!("could not extend lock: {e:?}");
lg_opt.take();
}
}
} else if let Some(l) = try_lock(&lm, &lock_id, ttl_millis as usize).await {
lg_opt = Some(LockGuard { lock: l });
} else {
tracing::error!("could not re-lock key_id {lock_id}");
}
}
}
}

async fn try_lock<'a>(lm: &'a LockManager, lock_id: &str, ttl_millis: usize) -> Option<Lock<'a>> {
match lm.lock(lock_id.as_bytes(), ttl_millis).await {
Ok(l) => Some(l),
Err(e) => {
tracing::warn!("could not lock key_id {lock_id}: {e:?}");
None
}
}
}
2 changes: 1 addition & 1 deletion docs/architecture/builder.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ These can be tweaked to modify the bundler's profitability.

### Gas Limit

The proposer limits the amount of UO gas that it will attempt to put into a single single bundle to ensure that transactions are below the gas cap of a block. This limit is calculated by summing the maximum gas usage of each UO in the bundle. If a UO puts the bundle over this limit, it (and all following UOs) will be skipped (but not removed from the pool).
The proposer limits the amount of UO gas that it will attempt to put into a single bundle to ensure that transactions are below the gas cap of a block. This limit is calculated by summing the maximum gas usage of each UO in the bundle. If a UO puts the bundle over this limit, it (and all following UOs) will be skipped (but not removed from the pool).

The maximum gas usage of each UO is a function of its `preVerificationGas`, `verificationGasLimit`, and `callGasLimit`.

Expand Down
2 changes: 1 addition & 1 deletion docs/architecture/pool.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ The `Pool` supports a very simple sharding scheme in its `best_operations` inter

User operations are assigned to a shard by their sender address modulo the number of shards.

Callers can use this feature to unsure that multiple callers are returned a disjoint set of user operations by sender. Callers should ensure that there is exactly 1 caller assigned to each shard index, else risk bundle invalidations (> 1 assigned) or orphaned user operations (0 assigned).
Callers can use this feature to ensure that multiple callers are returned a disjoint set of user operations by sender. Callers should ensure that there is exactly 1 caller assigned to each shard index, else risk bundle invalidations (> 1 assigned) or orphaned user operations (0 assigned).

## Alternative Mempools (in preview)

Expand Down
2 changes: 1 addition & 1 deletion docs/architecture/rpc.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Method defined by the [ERC-4337 spec](https://github.com/eth-infinitism/account-

### `rundler_` Namespace

Rundler specifc methods that are not specified by the ERC-4337 spec.
Rundler specific methods that are not specified by the ERC-4337 spec.

| Method | Supported |
| ------ | :-----------: |
Expand Down
2 changes: 1 addition & 1 deletion docs/proto.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ Rundler builds on [Tonic](https://github.com/hyperium/tonic) to power lightning

## Style Guide

Rundler largely relies on the canonical [protobuf style guide](https://protobuf.dev/programming-guides/style/). There are a few minor differences captured in `buf.yaml` to support Tonic best practices. Rundler use [buf](https://buf.build/) to lint the `.proto` files. To use `buf` run `buf lint protos/.`. To install `buf` on Macs, run `brew install bufbuild/buf/buf`.
Rundler largely relies on the canonical [protobuf style guide](https://protobuf.dev/programming-guides/style/). There are a few minor differences captured in `buf.yaml` to support Tonic best practices. Rundler uses [buf](https://buf.build/) to lint the `.proto` files. To use `buf` run `buf lint protos/.`. To install `buf` on Macs, run `brew install bufbuild/buf/buf`.

0 comments on commit 593b260

Please sign in to comment.