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
19 changes: 11 additions & 8 deletions src/apis/orderbookapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,29 @@
FAIL_CODE,
)

PROD_BASE_URL = "https://api.cow.fi/mainnet/api/v1/"
BARN_BASE_URL = "https://barn.api.cow.fi/mainnet/api/v1/"


class OrderbookAPI:
"""
Class for fetching data from a Web3 API.
"""

def __init__(self) -> None:
def __init__(self, chain_name: str) -> None:
self.logger = get_logger()
self.prod_url_prefix = f"https://api.cow.fi/{chain_name}/api/v1/"
self.barn_url_prefix = f"https://barn.api.cow.fi/{chain_name}/api/v1/"

def get_solver_competition_data(self, tx_hash: str) -> Optional[dict[str, Any]]:
"""
Get solver competition data from a transaction hash.
The returned dict follows the schema outlined here:
https://api.cow.fi/docs/#/default/get_api_v1_solver_competition_by_tx_hash__tx_hash_
"""
prod_endpoint_url = f"{PROD_BASE_URL}solver_competition/by_tx_hash/{tx_hash}"
barn_endpoint_url = f"{BARN_BASE_URL}solver_competition/by_tx_hash/{tx_hash}"
prod_endpoint_url = (
f"{self.prod_url_prefix}solver_competition/by_tx_hash/{tx_hash}"
)
barn_endpoint_url = (
f"{self.barn_url_prefix}solver_competition/by_tx_hash/{tx_hash}"
)
solver_competition_data: Optional[dict[str, Any]] = None
try:
json_competition_data = requests.get(
Expand Down Expand Up @@ -65,8 +68,8 @@ def get_order_data(self, uid: str) -> dict[str, Any] | None:
The returned dict follows the schema outlined here:
https://api.cow.fi/docs/#/default/get_api_v1_orders__UID_
"""
prod_endpoint_url = f"{PROD_BASE_URL}orders/{uid}"
barn_endpoint_url = f"{BARN_BASE_URL}orders/{uid}"
prod_endpoint_url = f"{self.prod_url_prefix}orders/{uid}"
barn_endpoint_url = f"{self.barn_url_prefix}orders/{uid}"
order_data: Optional[dict[str, Any]] = None
try:
json_order_data = requests.get(
Expand Down
6 changes: 6 additions & 0 deletions src/apis/web3api.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ def __init__(self) -> None:
)
self.logger = get_logger()

def get_chain_id(self) -> int:
"""
Function that returns the chain id
"""
return self.web_3.eth.chain_id

def get_current_block_number(self) -> Optional[int]:
"""
Function that returns the current block number
Expand Down
2 changes: 2 additions & 0 deletions src/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,5 @@
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"
}

CHAIN_ID_TO_NAME = {1: "mainnet", 100: "xdai", 42161: "arbitrum_one", 8453: "base"}
16 changes: 11 additions & 5 deletions src/daemon.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
""" A daemon to run tests on settlements.
"""A daemon to run tests on settlements.
An infinite loop is started which listens to CoW Protocol trade events. If such an event happens,
the correstonding transaction hash is added to the queue of the individual tests.

Expand All @@ -10,6 +10,7 @@
import time
from typing import Optional
from src.apis.web3api import Web3API
from src.apis.orderbookapi import OrderbookAPI
from src.monitoring_tests.solver_competition_surplus_test import (
SolverCompetitionSurplusTest,
)
Expand All @@ -19,21 +20,26 @@
from src.monitoring_tests.high_score_test import (
HighScoreTest,
)
from src.constants import SLEEP_TIME_IN_SEC
from src.constants import SLEEP_TIME_IN_SEC, CHAIN_ID_TO_NAME


def main() -> None:
"""
daemon function that runs as highlighted in docstring.
"""
web3_api = Web3API()
chain_id = web3_api.get_chain_id()
chain_name = CHAIN_ID_TO_NAME[chain_id]
orderbook_api = OrderbookAPI(chain_name)

# initialize tests
tests = [
SolverCompetitionSurplusTest(),
MEVBlockerRefundsMonitoringTest(),
HighScoreTest(),
SolverCompetitionSurplusTest(orderbook_api),
HighScoreTest(orderbook_api),
]
# special case for mainnet as MEV Blocker only exists on mainnet
if chain_name == "mainnet":
tests.append(MEVBlockerRefundsMonitoringTest(web3_api))

start_block: Optional[int] = None

Expand Down
4 changes: 2 additions & 2 deletions src/monitoring_tests/combinatorial_auction_surplus_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ class CombinatorialAuctionSurplusTest(BaseTest):
with our current mechanism.
"""

def __init__(self) -> None:
def __init__(self, orderbook_api: OrderbookAPI) -> None:
super().__init__()
self.orderbook_api = OrderbookAPI()
self.orderbook_api = orderbook_api

def run_combinatorial_auction(self, competition_data: dict[str, Any]) -> bool:
"""Run combinatorial auction on competition data.
Expand Down
6 changes: 3 additions & 3 deletions src/monitoring_tests/cost_coverage_zero_signed_fee.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ class CostCoverageForZeroSignedFee(BaseTest):
sent as zero-signed fee orders from CoW Swap.
"""

def __init__(self) -> None:
def __init__(self, web3_api: Web3API, orderbook_api: OrderbookAPI) -> None:
super().__init__()
self.web3_api = Web3API()
self.orderbook_api = OrderbookAPI()
self.web3_api = web3_api
self.orderbook_api = orderbook_api
self.cost_coverage_per_solver: Dict[str, float] = {}
self.total_coverage_per_solver: Dict[str, float] = {}
self.original_block = self.web3_api.get_current_block_number()
Expand Down
4 changes: 2 additions & 2 deletions src/monitoring_tests/high_score_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ class HighScoreTest(BaseTest):
is above certain threshold
"""

def __init__(self) -> None:
def __init__(self, orderbook_api: OrderbookAPI) -> None:
super().__init__()
self.orderbook_api = OrderbookAPI()
self.orderbook_api = orderbook_api

def compute_winning_score(self, competition_data: dict[str, Any]) -> bool:
"""
Expand Down
4 changes: 2 additions & 2 deletions src/monitoring_tests/mev_blocker_kickbacks_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ class MEVBlockerRefundsMonitoringTest(BaseTest):
generates a log/alert if this is the case.
"""

def __init__(self) -> None:
def __init__(self, web3_api: Web3API) -> None:
super().__init__()
self.web3_api = Web3API()
self.web3_api = web3_api

def run(self, tx_hash: str) -> bool:
"""
Expand Down
6 changes: 3 additions & 3 deletions src/monitoring_tests/partially_fillable_cost_coverage_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ class PartialFillCostCoverageTest(BaseTest):
Class for testing fees.
"""

def __init__(self) -> None:
def __init__(self, web3_api: Web3API, orderbook_api: OrderbookAPI) -> None:
super().__init__()
self.web3_api = Web3API()
self.orderbook_api = OrderbookAPI()
self.web3_api = web3_api
self.orderbook_api = orderbook_api

def run(self, tx_hash: str) -> bool:
"""
Expand Down
6 changes: 3 additions & 3 deletions src/monitoring_tests/reference_solver_surplus_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ class ReferenceSolverSurplusTest(BaseTest):
the executions of these orders by a reference solver.
"""

def __init__(self) -> None:
def __init__(self, web3_api: Web3API, orderbook_api: OrderbookAPI) -> None:
super().__init__()
self.web3_api = Web3API()
self.orderbook_api = OrderbookAPI()
self.web3_api = web3_api
self.orderbook_api = orderbook_api
self.auction_instance_api = AuctionInstanceAPI()
self.solver_api = SolverAPI()

Expand Down
6 changes: 3 additions & 3 deletions src/monitoring_tests/solver_competition_surplus_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ class SolverCompetitionSurplusTest(BaseTest):
the different executions of these orders by other solvers in the competition.
"""

def __init__(self) -> None:
def __init__(self, orderbook_api: OrderbookAPI) -> None:
super().__init__()
self.orderbook_api = OrderbookAPI()
self.orderbook_api = orderbook_api

def compare_orders_surplus(self, competition_data: dict[str, Any]) -> bool:
"""
Expand Down Expand Up @@ -119,7 +119,7 @@ def get_uid_order_execution(
def run(self, tx_hash: str) -> bool:
"""
Wrapper function for the whole test. Checks if solver competition data is retrievable
and runs EBBO test, else returns True to add to list of unchecked hashes.
and runs EBBO test, else returns False to add to list of unchecked hashes.
"""

solver_competition_data = self.orderbook_api.get_solver_competition_data(
Expand Down
4 changes: 2 additions & 2 deletions src/monitoring_tests/uniform_directed_prices_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ class UniformDirectedPricesTest(BaseTest):
as introduced in CIP-38, is satisfied.
"""

def __init__(self) -> None:
def __init__(self, orderbook_api: OrderbookAPI) -> None:
super().__init__()
self.orderbook_api = OrderbookAPI()
self.orderbook_api = orderbook_api

def check_udp(self, competition_data: dict[str, Any]) -> bool:
"""
Expand Down