Skip to content
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
10 changes: 9 additions & 1 deletion .circleci/tests/mev.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
{
"mev_type": "full",
"additional_services": [
"tx_spammer",
"blob_spammer",
"custom_flood",
"el_forkmon",
"beacon_metrics_gazer",
"dora",
"prometheus_grafana"
],
"mev_params": {
"launch_custom_flood": true,
"mev_relay_image": "flashbots/mev-boost-relay:0.27"
},
"network_params": {
Expand Down
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,8 @@ To configure the package behaviour, you can modify your `network_params.json` fi
"additional_services": [
"tx_spammer",
"blob_spammer",
"goomy_blob"
"custom_flood",
"goomy_blob",
"el_forkmon",
"beacon_metrics_gazer",
"dora",
Expand Down Expand Up @@ -307,9 +308,10 @@ To configure the package behaviour, you can modify your `network_params.json` fi
"mev_flood_extra_args": [],
// Number of seconds between bundles for mev-flood
"mev_flood_seconds_per_bundle": 15,
// A custom flood script that increases the balance of the coinbase addresss leading to more reliable
// payload delivery
"launch_custom_flood": false
// Optional parameters to send to the custom_flood script that sends reliable payloads
"custom_flood_params": {
"interval_between_transactions": 1
}
},
// A list of locators for grafana dashboards to be loaded be the grafana service
"grafana_additional_dashboards": []
Expand Down
1 change: 0 additions & 1 deletion examples/capella-mev.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
},
"mev_params": {
"mev_flood_seconds_per_bundle": 12,
"launch_custom_flood": false,
"mev_flood_extra_args": [ "--txsPerBundle=300" ],
"mev_flood_image": "flashbots/mev-flood:0.0.9",
"mev_relay_image": "flashbots/mev-boost-relay:0.27.0"
Expand Down
15 changes: 8 additions & 7 deletions main.star
Original file line number Diff line number Diff line change
Expand Up @@ -190,13 +190,6 @@ def run(plan, args={}):
mev_params.mev_flood_seconds_per_bundle,
genesis_constants.PRE_FUNDED_ACCOUNTS,
)
if args_with_right_defaults.mev_params.launch_custom_flood:
mev_custom_flood_module.spam_in_background(
plan,
genesis_constants.PRE_FUNDED_ACCOUNTS[-1].private_key,
genesis_constants.PRE_FUNDED_ACCOUNTS[0].address,
el_uri,
)
mev_endpoints.append(endpoint)

# spin up the mev boost contexts if some endpoints for relays have been passed
Expand Down Expand Up @@ -313,6 +306,14 @@ def run(plan, args={}):
elif additional_service == "prometheus_grafana":
# Allow prometheus to be launched last so is able to collect metrics from other services
launch_prometheus_grafana = True
elif additional_service == "custom_flood":
mev_custom_flood_module.spam_in_background(
plan,
genesis_constants.PRE_FUNDED_ACCOUNTS[-1].private_key,
genesis_constants.PRE_FUNDED_ACCOUNTS[0].address,
el_uri,
args_with_right_defaults.custom_flood_params,
)
else:
fail("Invalid additional service %s" % (additional_service))
if launch_prometheus_grafana:
Expand Down
3 changes: 1 addition & 2 deletions network_params.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@
"mev_builder_extra_args": [],
"mev_flood_image": "flashbots/mev-flood",
"mev_flood_extra_args": [],
"mev_flood_seconds_per_bundle": 15,
"launch_custom_flood": false
"mev_flood_seconds_per_bundle": 15
},
"grafana_additional_dashboards": []
}
12 changes: 9 additions & 3 deletions src/mev_custom_flood/mev_custom_flood_launcher.star
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ PYTHON_IMAGE = "python:3.11-alpine"
CUSTOM_FLOOD_SERVICE_NAME = "mev-custom-flood"


def spam_in_background(plan, sender_key, receiver_key, el_uri):
def spam_in_background(plan, sender_key, receiver_key, el_uri, params):
sender_script = plan.upload_files("./sender.py")

plan.add_service(
Expand All @@ -21,12 +21,18 @@ def spam_in_background(plan, sender_key, receiver_key, el_uri):

plan.exec(
service_name=CUSTOM_FLOOD_SERVICE_NAME,
recipe=ExecRecipe(["pip", "install", "web3"]),
recipe=ExecRecipe(["pip", "install", "web3", "click"]),
)

plan.exec(
service_name=CUSTOM_FLOOD_SERVICE_NAME,
recipe=ExecRecipe(
["/bin/sh", "-c", "nohup python /tmp/sender.py > /dev/null 2>&1 &"]
[
"/bin/sh",
"-c",
"nohup python /tmp/sender.py --interval_between_transactions {} > /dev/null 2>&1 &".format(
params.interval_between_transactions
),
]
),
)
68 changes: 36 additions & 32 deletions src/mev_custom_flood/sender.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@
this is s a really dumb script that sends tokens to the receiver from the sender every 3 seconds
this is being used as of 2023-09-06 to guarantee that payloads are delivered
"""
from functools import partial

from web3 import Web3
from web3.middleware import construct_sign_and_send_raw_middleware
import os
import time
import logging
import click


VALUE_TO_SEND = 0x9184

Expand All @@ -17,49 +20,50 @@
datefmt='%H:%M:%S',
level=logging.DEBUG)

# this is the last prefunded address
SENDER = os.getenv("SENDER_PRIVATE_KEY", "17fdf89989597e8bcac6cdfcc001b6241c64cece2c358ffc818b72ca70f5e1ce")
# this is the first prefunded address
RECEIVER = os.getenv("RECEIVER_PUBLIC_KEY", "0x878705ba3f8Bc32FCf7F4CAa1A35E72AF65CF766")
EL_URI = os.getenv("EL_RPC_URI", 'http://0.0.0.0:53913')

def flood():
# this is the last prefunded address
sender = os.getenv("SENDER_PRIVATE_KEY", "17fdf89989597e8bcac6cdfcc001b6241c64cece2c358ffc818b72ca70f5e1ce")
# this is the first prefunded address
receiver = os.getenv("RECEIVER_PUBLIC_KEY", "0x878705ba3f8Bc32FCf7F4CAa1A35E72AF65CF766")
el_uri = os.getenv("EL_RPC_URI", 'http://0.0.0.0:53913')

logging.info(f"Using sender {sender} receiver {receiver} and el_uri {el_uri}")

w3 = Web3(Web3.HTTPProvider(el_uri))

sender_account = w3.eth.account.from_key(sender)

while True:
time.sleep(3)
def send_transaction():
# Setting w3 as constant causes recursion exceeded error after ~500 transactions
Comment thread
h4ck3rk3y marked this conversation as resolved.
# Thus it's created everytime a transaction is sent
w3 = Web3(Web3.HTTPProvider(EL_URI))

w3.middleware_onion.add(construct_sign_and_send_raw_middleware(sender_account))
sender_account = w3.eth.account.from_key(SENDER)
w3.middleware_onion.add(construct_sign_and_send_raw_middleware(sender_account))

transaction = {
"from": sender_account.address,
"value": VALUE_TO_SEND,
"to": receiver,
"data": "0xabcd",
"gasPrice": w3.eth.gas_price,
"nonce": w3.eth.get_transaction_count(sender_account.address)
}
transaction = {
"from": sender_account.address,
"value": VALUE_TO_SEND,
"to": RECEIVER,
"data": "0xabcd",
"gasPrice": w3.eth.gas_price,
"nonce": w3.eth.get_transaction_count(sender_account.address)
}

estimated_gas = w3.eth.estimate_gas(transaction)
transaction["gas"] = estimated_gas

transaction["gas"] = estimated_gas
tx_hash = w3.eth.send_transaction(transaction)

tx_hash = w3.eth.send_transaction(transaction)
tx = w3.eth.get_transaction(tx_hash)
logging.info(tx_hash.hex())
assert tx["from"] == sender_account.address

tx = w3.eth.get_transaction(tx_hash)
logging.info(tx_hash.hex())
assert tx["from"] == sender_account.address
def delayed_send(interval_between_transactions):
send_transaction()
time.sleep(interval_between_transactions)


def run_infinitely():
@click.command()
@click.option('--interval_between_transactions', default=0.5, help='Interval between successive transaction sends (in seconds). The value may be an integer or decimal')
def run_infinitely(interval_between_transactions):
logging.info(f"Using sender {SENDER} receiver {RECEIVER} and el_uri {EL_URI}")
spam = send_transaction if interval_between_transactions == 0 else partial(delayed_send, interval_between_transactions)
while True:
try:
flood()
spam()
except Exception as e:
print("e")
print("restarting flood as previous one failed")
Expand Down
20 changes: 16 additions & 4 deletions src/package_io/parse_input.star
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ ATTR_TO_BE_SKIPPED_AT_ROOT = (
"mev_params",
"goomy_blob_params",
"tx_spammer_params",
"custom_flood_params",
)

package_io_constants = import_module("../package_io/constants.star")
Expand All @@ -65,6 +66,7 @@ def parse_input(plan, input_args):
result["additional_services"] = DEFAULT_ADDITIONAL_SERVICES
result["grafana_additional_dashboards"] = []
result["tx_spammer_params"] = get_default_tx_spammer_params()
result["custom_flood_params"] = get_default_custom_flood_params()

for attr in input_args:
value = input_args[attr]
Expand All @@ -80,6 +82,10 @@ def parse_input(plan, input_args):
for sub_attr in input_args["tx_spammer_params"]:
sub_value = input_args["tx_spammer_params"][sub_attr]
result["tx_spammer_params"][sub_attr] = sub_value
elif attr == "custom_flood_params":
for sub_attr in input_args["custom_flood_params"]:
sub_value = input_args["custom_flood_params"][sub_attr]
result["custom_flood_params"][sub_attr] = sub_value

if result.get("mev_type") in ("mock", "full"):
result = enrich_mev_extra_params(
Expand All @@ -101,7 +107,6 @@ def parse_input(plan, input_args):
)

result["goomy_blob_params"] = get_default_goomy_blob_params()

return struct(
participants=[
struct(
Expand Down Expand Up @@ -168,14 +173,18 @@ def parse_input(plan, input_args):
mev_flood_seconds_per_bundle=result["mev_params"][
"mev_flood_seconds_per_bundle"
],
launch_custom_flood=result["mev_params"]["launch_custom_flood"],
),
tx_spammer_params=struct(
tx_spammer_extra_args=result["tx_spammer_params"]["tx_spammer_extra_args"],
),
goomy_blob_params=struct(
goomy_blob_args=result["goomy_blob_params"]["goomy_blob_args"],
),
custom_flood_params=struct(
interval_between_transactions=result["custom_flood_params"][
"interval_between_transactions"
],
),
launch_additional_services=result["launch_additional_services"],
additional_services=result["additional_services"],
wait_for_finalization=result["wait_for_finalization"],
Expand Down Expand Up @@ -399,8 +408,6 @@ def get_default_mev_params():
"mev_flood_image": "flashbots/mev-flood",
"mev_flood_extra_args": [],
"mev_flood_seconds_per_bundle": 15,
# this is a simple script that increases the balance of the coinbase address at a cadence
"launch_custom_flood": False,
}


Expand All @@ -412,6 +419,11 @@ def get_default_goomy_blob_params():
return {"goomy_blob_args": []}


def get_default_custom_flood_params():
# this is a simple script that increases the balance of the coinbase address at a cadence
return {"interval_between_transactions": 1}


# TODO perhaps clean this up into a map
def enrich_mev_extra_params(parsed_arguments_dict, mev_prefix, mev_port, mev_type):
for index, participant in enumerate(parsed_arguments_dict["participants"]):
Expand Down