Skip to content

Commit

Permalink
e2e pytest introduction (#190)
Browse files Browse the repository at this point in the history
* chain advancing test

* test_preconfirm_transaction and test_p2p_preconfirmation

* git ignore for tests

* readme updated

* venv to readme

* review
  • Loading branch information
mskrzypkows authored Dec 5, 2024
1 parent b3d7243 commit 9327928
Show file tree
Hide file tree
Showing 10 changed files with 158 additions and 3 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/Node/target
.vscode
.env
tools/tx_spammer/venv
venv
.DS_Store
.sum
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM docker.io/library/rust:1.80 AS builder
FROM docker.io/library/rust:1.83 AS builder

# Set the working directory inside the container
WORKDIR /usr/src/taiko_preconf_avs_node
Expand Down
9 changes: 9 additions & 0 deletions e2e_tests/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Ethereum L1 RPC URL (e.g., local node, testnet, or mainnet)
L1_RPC_URL=http://localhost:8545

# L2 (Taiko) RPC URL
L2_RPC_URL=http://localhost:8546


# Test account private key (optional, for specific tests)
TEST_L2_PREFUNDED_PRIVATE_KEY=370e47f3c39cf4d03cb87cb71a268776421cdc22c39aa81f1e5ba19df19202f1
4 changes: 4 additions & 0 deletions e2e_tests/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
__pycache__/
*.py[cod]
*$py.class
.pytest_cache/
29 changes: 29 additions & 0 deletions e2e_tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# End to end preconfirmation tests

This is a collection of end to end tests for the preconfirmation service.

It requires full stack to be up and running. Usually by running
```
kurtosis run --enclave taiko-preconf-devnet . --args-file network_params.yaml
```
from the main branch of https://github.com/NethermindEth/preconfirm-devnet-package.

It also requires a `.env` file to be present in the root directory. You can copy `.env.example` file into `.env` and fill in the required values.

Create venv:
```
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
```

To run all tests:

```
pytest
```

To run a specific test with output printed:
```
pytest -s -v -k test_name
```
22 changes: 22 additions & 0 deletions e2e_tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import pytest
from web3 import Web3
from eth_account import Account
import os
from dotenv import load_dotenv

load_dotenv()

@pytest.fixture(scope="session")
def l1_client():
w3 = Web3(Web3.HTTPProvider(os.getenv("L1_RPC_URL")))
return w3

@pytest.fixture(scope="session")
def l2_client_node1():
w3 = Web3(Web3.HTTPProvider(os.getenv("L2_RPC_URL_NODE1")))
return w3

@pytest.fixture(scope="session")
def l2_client_node2():
w3 = Web3(Web3.HTTPProvider(os.getenv("L2_RPC_URL_NODE2")))
return w3
3 changes: 3 additions & 0 deletions e2e_tests/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
web3>=6.0.0
python-dotenv>=1.0.0
pytest>=7.4.0
66 changes: 66 additions & 0 deletions e2e_tests/test_avs_node.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import pytest
import requests
from web3 import Web3
import os
from dotenv import load_dotenv
import sys
from utils import *

load_dotenv()

l2_prefunded_priv_key = os.getenv("TEST_L2_PREFUNDED_PRIVATE_KEY")
if not l2_prefunded_priv_key:
raise Exception("Environment variable TEST_L2_PREFUNDED_PRIVATE_KEY not set")


def test_chain_ids(l1_client, l2_client_node1, l2_client_node2):
"""Test to verify the chain IDs of L1 and L2 networks"""
l1_chain_id = l1_client.eth.chain_id
l2_chain_id_node1 = l2_client_node1.eth.chain_id
l2_chain_id_node2 = l2_client_node2.eth.chain_id

print(f"L1 Chain ID: {l1_chain_id}")
print(f"L2 Chain ID Node 1: {l2_chain_id_node1}")
print(f"L2 Chain ID Node 2: {l2_chain_id_node2}")

assert l1_chain_id > 0, "L1 chain ID should be greater than 0"
assert l2_chain_id_node1 > 0, "L2 chain ID should be greater than 0"

assert l1_chain_id != l2_chain_id_node1, "L1 and L2 should have different chain IDs"
assert l2_chain_id_node1 == l2_chain_id_node2, "L2 nodes should have the same chain IDs"

def test_preconfirm_transaction(l1_client, l2_client_node1):
account = l2_client_node1.eth.account.from_key(l2_prefunded_priv_key)
nonce = l2_client_node1.eth.get_transaction_count(account.address)
l2_block_number = l2_client_node1.eth.block_number

send_transaction(nonce, account, '0.00005', l2_client_node1, l2_prefunded_priv_key)

wait_for_secs(4)

l2_block_number_after = l2_client_node1.eth.block_number

print(f"L2 Block Number: {l2_block_number}")
print(f"L2 Block Number After: {l2_block_number_after}")

assert l2_block_number_after > l2_block_number, "L2 block number should increase after sending a transaction"

def test_p2p_preconfirmation(l2_client_node1, l2_client_node2):
account = l2_client_node1.eth.account.from_key(l2_prefunded_priv_key)
nonce = l2_client_node1.eth.get_transaction_count(account.address)
l2_node_2_block_number = l2_client_node2.eth.block_number

send_transaction(nonce, account, '0.00006', l2_client_node1, l2_prefunded_priv_key)

wait_for_secs(4)

l2_node_2_block_number_after = l2_client_node2.eth.block_number
node_1_block_hash = l2_client_node1.eth.get_block(l2_node_2_block_number_after).hash
node_2_block_hash = l2_client_node2.eth.get_block(l2_node_2_block_number_after).hash

print(f"L2 Node 2 Block Number: {l2_node_2_block_number}")
print(f"L2 Node 2 Block Number After: {l2_node_2_block_number_after}")

assert l2_node_2_block_number_after > l2_node_2_block_number, "L2 Node 2 block number should increase after sending a transaction"

assert node_2_block_hash == node_1_block_hash, "L2 Node 1 and L2 Node 2 should have the same block hash after sending a transaction"
22 changes: 22 additions & 0 deletions e2e_tests/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import time

def send_transaction(nonce : int, account, amount, eth_client, private_key):
tx = {
'nonce': nonce,
'to': "0x0000000000000000000000000000000000000001",
'value': eth_client.to_wei(amount, 'ether'),
'gas': 40000,
'gasPrice': eth_client.eth.gas_price,
'chainId': eth_client.eth.chain_id
}
print(f'RPC URL: {eth_client.provider.endpoint_uri}, Sending from: {account.address}')
signed_tx = eth_client.eth.account.sign_transaction(tx, private_key)
tx_hash = eth_client.eth.send_raw_transaction(signed_tx.raw_transaction)
print(f'Transaction sent: {tx_hash.hex()}')
return tx_hash

def wait_for_secs(seconds):
for i in range(seconds, 0, -1):
print(f'Waiting for {i:02d} seconds', end='\r')
time.sleep(1)
print('')
2 changes: 1 addition & 1 deletion tools/tx_spammer/tx_spammer.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def send_transaction(nonce : int):
'nonce': nonce,
'to': recipient,
'value': amount,
'gas': 21000,
'gas': 40000,
'gasPrice': w3.to_wei('10', 'gwei'),
'chainId': w3.eth.chain_id
}
Expand Down

0 comments on commit 9327928

Please sign in to comment.