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

feat(admin): create admin namespace and add paymaster clear / toggle for reputation #570

Merged
merged 14 commits into from
Feb 2, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
18 changes: 18 additions & 0 deletions bin/rundler/src/cli/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,22 @@ pub struct PoolArgs {
default_value = "10"
)]
pub throttled_entity_live_blocks: u64,

#[arg(
long = "pool.paymaster_tracking_enabled",
name = "pool.paymaster_tracking_enabled",
env = "POOL_PAYMASTER_TRACKING_ENABLED",
default_value = "true"
)]
pub paymaster_tracking_enabled: bool,

#[arg(
long = "pool.reputation_tracking_enabled",
name = "pool.reputation_tracking_enabled",
env = "POOL_REPUTATION_TRACKING_ENABLED",
default_value = "true"
)]
pub reputation_tracking_enabled: bool,
}

impl PoolArgs {
Expand Down Expand Up @@ -167,6 +183,8 @@ impl PoolArgs {
mempool_channel_configs: mempool_channel_configs.clone(),
throttled_entity_mempool_count: self.throttled_entity_mempool_count,
throttled_entity_live_blocks: self.throttled_entity_live_blocks,
paymaster_tracking_enabled: self.paymaster_tracking_enabled,
reputation_tracking_enabled: self.reputation_tracking_enabled,
})
})
.collect::<anyhow::Result<Vec<PoolConfig>>>()?;
Expand Down
2 changes: 1 addition & 1 deletion bin/rundler/src/cli/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub struct RpcArgs {
env = "RPC_API",
default_value = "eth,rundler",
value_delimiter = ',',
value_parser = ["eth", "debug", "rundler"]
value_parser = ["eth", "debug", "rundler", "admin"]
)]
api: Vec<String>,

Expand Down
18 changes: 18 additions & 0 deletions crates/pool/proto/op_pool/op_pool.proto
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,9 @@ service OpPool {
// Streaming API to subscribe to be updated upon a new block being added to (or reorged onto)
// the chain.
rpc SubscribeNewHeads(SubscribeNewHeadsRequest) returns (stream SubscribeNewHeadsResponse);

// Clears the bundler mempool and reputation data of paymasters/accounts/factories/aggregators
rpc AdminSetTracking(AdminSetTrackingRequest) returns (AdminSetTrackingResponse);
}

message GetSupportedEntryPointsRequest {}
Expand Down Expand Up @@ -293,6 +296,7 @@ message UpdateEntitiesSuccess {}
message DebugClearStateRequest {
bool clear_mempool = 1;
bool clear_reputation = 2;
bool clear_paymaster = 3;
}
message DebugClearStateResponse {
oneof result {
Expand Down Expand Up @@ -355,6 +359,20 @@ message NewHead {
uint64 block_number = 2;
}

message AdminSetTrackingRequest {
// The serialized entry point address via which the UserOperation is being submitted
bytes entry_point = 1;
bool paymaster = 2;
bool reputation = 3;
}
message AdminSetTrackingResponse {
oneof result {
AdminSetTrackingSuccess success = 1;
MempoolError failure = 2;
}
}
message AdminSetTrackingSuccess {}

message Reputation {
// The (serialized) address to set the reputation for
bytes address = 1;
Expand Down
9 changes: 8 additions & 1 deletion crates/pool/src/mempool/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ pub trait Mempool: Send + Sync + 'static {
/// Debug methods

/// Clears the mempool of UOs or reputation of all addresses
fn clear_state(&self, clear_mempool: bool, clear_reputation: bool);
fn clear_state(&self, clear_mempool: bool, clear_paymaster: bool, clear_reputation: bool);

/// Dumps the mempool's reputation tracking
fn dump_reputation(&self) -> Vec<Reputation>;
Expand All @@ -108,6 +108,9 @@ pub trait Mempool: Send + Sync + 'static {

/// Reset paymater state
async fn reset_confirmed_paymaster_balances(&self) -> MempoolResult<()>;

/// Turns on and off tracking errors
fn set_tracking(&self, paymaster: bool, reputation: bool);
}

/// Config for the mempool
Expand Down Expand Up @@ -143,6 +146,10 @@ pub struct PoolConfig {
pub throttled_entity_mempool_count: u64,
/// The maximum number of blocks a user operation with a throttled entity can stay in the mempool
pub throttled_entity_live_blocks: u64,
/// Boolean field used to toggle the operation of the paymaster tracker
pub paymaster_tracking_enabled: bool,
/// Boolean field used to toggle the operation of the reputation tracker
pub reputation_tracking_enabled: bool,
}

/// Stake status structure
Expand Down
69 changes: 61 additions & 8 deletions crates/pool/src/mempool/paymaster.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,14 @@ pub(crate) struct PaymasterTracker {
user_op_fees: HashMap<UserOperationId, UserOpFees>,
/// map for paymaster balance status
paymaster_balances: HashMap<Address, PaymasterBalance>,
/// boolean for operation of tracker
tracker_enabled: bool,
}

impl PaymasterTracker {
pub(crate) fn new() -> Self {
pub(crate) fn new(tracker_enabled: bool) -> Self {
Self {
tracker_enabled,
..Default::default()
}
}
Expand All @@ -42,6 +45,10 @@ impl PaymasterTracker {
self.paymaster_balances.contains_key(&paymaster)
}

pub(crate) fn set_paymaster_tracker(&mut self, tracking_enabled: bool) {
self.tracker_enabled = tracking_enabled;
}

pub(crate) fn clear(&mut self) {
self.user_op_fees.clear();
self.paymaster_balances.clear();
Expand Down Expand Up @@ -138,7 +145,8 @@ impl PaymasterTracker {
let id = po.uo.id();
let max_op_cost = po.uo.max_gas_cost();

if paymaster_metadata.pending_balance.lt(&max_op_cost) {
// Only return an error if tracking is enabled
if paymaster_metadata.pending_balance.lt(&max_op_cost) && self.tracker_enabled {
Comment on lines +148 to +149
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something that confused me about the naming conventions here. We're still actually preforming the tracking, correct? We're just not allowing the tracking to cause UOs to be rejected?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeh the naming was something I was not too sure about either. Maybe like only_tracking or blocking_enabled would be more fit for purpose

return Err(MempoolError::PaymasterBalanceTooLow(
max_op_cost,
paymaster_metadata.pending_balance,
Expand Down Expand Up @@ -308,7 +316,7 @@ mod tests {

#[test]
fn new_uo_unused_paymaster() {
let mut paymaster_tracker = PaymasterTracker::new();
let mut paymaster_tracker = PaymasterTracker::new(true);

let paymaster = Address::random();
let sender = Address::random();
Expand Down Expand Up @@ -354,7 +362,7 @@ mod tests {

#[test]
fn new_uo_not_enough_balance() {
let mut paymaster_tracker = PaymasterTracker::new();
let mut paymaster_tracker = PaymasterTracker::new(true);

let paymaster = Address::random();
let sender = Address::random();
Expand All @@ -381,9 +389,54 @@ mod tests {
assert!(res.is_err());
}

#[test]
fn new_uo_not_enough_balance_tracking_disabled() {
let mut paymaster_tracker = PaymasterTracker::new(false);

let paymaster = Address::random();
let sender = Address::random();
let paymaster_balance = U256::from(5);
let confirmed_balance = U256::from(5);
let uo = UserOperation {
sender,
call_gas_limit: 10.into(),
pre_verification_gas: 10.into(),
verification_gas_limit: 10.into(),
max_fee_per_gas: 1.into(),
..Default::default()
};

let paymaster_meta = PaymasterMetadata {
address: paymaster,
pending_balance: paymaster_balance,
confirmed_balance,
};

let po = demo_pool_op(uo);

let res = paymaster_tracker.add_or_update_balance(&po, &paymaster_meta);
assert!(res.is_ok());
assert_eq!(
paymaster_tracker
.paymaster_balances
.get(&paymaster)
.unwrap()
.confirmed,
5.into(),
);
assert_eq!(
paymaster_tracker
.paymaster_balances
.get(&paymaster)
.unwrap()
.pending,
30.into(),
);
}

#[test]
fn new_uo_not_enough_balance_existing_paymaster() {
let mut paymaster_tracker = PaymasterTracker::new();
let mut paymaster_tracker = PaymasterTracker::new(true);

let paymaster = Address::random();
let sender = Address::random();
Expand Down Expand Up @@ -421,7 +474,7 @@ mod tests {

#[test]
fn new_uo_existing_paymaster_valid_balance() {
let mut paymaster_tracker = PaymasterTracker::new();
let mut paymaster_tracker = PaymasterTracker::new(true);
let paymaster = Address::random();
let paymaster_balance = U256::from(100000000);
let pending_paymaster_balance = U256::from(10);
Expand Down Expand Up @@ -484,7 +537,7 @@ mod tests {

#[test]
fn replacement_uo_new_paymaster() {
let mut paymaster_tracker = PaymasterTracker::new();
let mut paymaster_tracker = PaymasterTracker::new(true);
let paymaster_0 = Address::random();
let paymaster_1 = Address::random();

Expand Down Expand Up @@ -563,7 +616,7 @@ mod tests {

#[test]
fn replacement_uo_same_paymaster() {
let mut paymaster_tracker = PaymasterTracker::new();
let mut paymaster_tracker = PaymasterTracker::new(true);
let sender = Address::random();
let paymaster = Address::random();
let paymaster_balance = U256::from(100000000);
Expand Down
38 changes: 25 additions & 13 deletions crates/pool/src/mempool/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ pub(crate) struct PoolInnerConfig {
min_replacement_fee_increase_percentage: u64,
throttled_entity_mempool_count: u64,
throttled_entity_live_blocks: u64,
paymaster_tracking_enabled: bool,
}

impl From<PoolConfig> for PoolInnerConfig {
Expand All @@ -54,6 +55,7 @@ impl From<PoolConfig> for PoolInnerConfig {
min_replacement_fee_increase_percentage: config.min_replacement_fee_increase_percentage,
throttled_entity_mempool_count: config.throttled_entity_mempool_count,
throttled_entity_live_blocks: config.throttled_entity_live_blocks,
paymaster_tracking_enabled: config.paymaster_tracking_enabled,
}
}
}
Expand Down Expand Up @@ -91,11 +93,11 @@ pub(crate) struct PoolInner {
impl PoolInner {
pub(crate) fn new(config: PoolInnerConfig) -> Self {
Self {
paymaster_balances: PaymasterTracker::new(config.paymaster_tracking_enabled),
config,
by_hash: HashMap::new(),
by_id: HashMap::new(),
best: BTreeSet::new(),
paymaster_balances: PaymasterTracker::new(),
mined_at_block_number_by_hash: HashMap::new(),
mined_hashes_with_block_numbers: BTreeSet::new(),
count_by_address: HashMap::new(),
Expand Down Expand Up @@ -355,7 +357,7 @@ impl PoolInner {
self.paymaster_balances.paymaster_exists(paymaster)
}

pub(crate) fn update_paymaster_balances_after_update(
pub(crate) fn update_paymaster_balances_after_updates(
&mut self,
deposits: &Vec<DepositInfo>,
unmined_entity_deposits: &Vec<DepositInfo>,
Expand All @@ -374,17 +376,26 @@ impl PoolInner {
}
}

pub(crate) fn clear(&mut self) {
self.by_hash.clear();
self.by_id.clear();
self.paymaster_balances.clear();
self.best.clear();
self.mined_at_block_number_by_hash.clear();
self.mined_hashes_with_block_numbers.clear();
self.count_by_address.clear();
self.pool_size = SizeTracker::default();
self.cache_size = SizeTracker::default();
self.update_metrics();
pub(crate) fn clear(&mut self, clear_mempool: bool, clear_paymaster: bool) {
if clear_mempool {
self.by_hash.clear();
self.by_id.clear();
self.best.clear();
self.mined_at_block_number_by_hash.clear();
self.mined_hashes_with_block_numbers.clear();
self.count_by_address.clear();
self.pool_size = SizeTracker::default();
self.cache_size = SizeTracker::default();
self.update_metrics();
}

if clear_paymaster {
self.paymaster_balances.clear();
}
}

pub(crate) fn set_tracking(&mut self, paymaster: bool) {
self.paymaster_balances.set_paymaster_tracker(paymaster);
}

fn enforce_size(&mut self) -> anyhow::Result<Vec<H256>> {
Expand Down Expand Up @@ -1037,6 +1048,7 @@ mod tests {
max_size_of_pool_bytes: 20 * mem_size_of_ordered_pool_op(),
throttled_entity_mempool_count: 4,
throttled_entity_live_blocks: 10,
paymaster_tracking_enabled: true,
}
}

Expand Down
Loading
Loading