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

Add Solana methods and feature for testing individual Solana methods #80

Merged
merged 5 commits into from
Apr 25, 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
13 changes: 13 additions & 0 deletions chainbench/profile/solana/all.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# """
# Solana profile (all supported methods).
# """

from locust import constant_pacing

from chainbench.user.methods.common import get_subclass_functions
from chainbench.user.methods.solana import SolanaMethods


class SolanaAllProfile(SolanaMethods):
wait_time = constant_pacing(1)
tasks = [task.method for task in get_subclass_functions(SolanaMethods)]
138 changes: 23 additions & 115 deletions chainbench/profile/solana/general.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,122 +17,30 @@
```
"""

from locust import constant_pacing, tag, task
from locust import constant_pacing

from chainbench.user import SolanaUser
from chainbench.util.rng import get_rng
from chainbench.user.http import assign_tasks
from chainbench.user.methods.solana import SolanaMethods


class SolanaProfile(SolanaUser):
class SolanaProfile(SolanaMethods):
wait_time = constant_pacing(1)

@task(1000)
def get_account_info_task(self):
self.make_rpc_call(
method="getAccountInfo",
params=self._get_account_info_params_factory(get_rng()),
),

@task(175)
def get_block_task(self):
self.make_rpc_call(
method="getBlock",
params=self._get_block_params_factory(get_rng()),
),

@task(150)
def get_token_accounts_by_owner(self):
self.make_rpc_call(
method="getTokenAccountsByOwner",
params=self._get_token_accounts_by_owner_params_factory(get_rng()),
),

@task(150)
def get_multiple_accounts(self):
self.make_rpc_call(
method="getMultipleAccounts",
params=self._get_multiple_accounts_params_factory(get_rng()),
),

@task(130)
def get_transaction(self):
self.make_rpc_call(
method="getTransaction",
params=self._get_transaction_params_factory(get_rng()),
),

@task(75)
def get_signatures_for_address(self):
self.make_rpc_call(
method="getSignaturesForAddress",
params=self._get_signatures_for_address_params_factory(get_rng()),
),

@task(75)
def get_latest_blockhash(self):
self.make_rpc_call(
method="getLatestBlockhash",
),

@task(75)
def get_balance(self):
self.make_rpc_call(
method="getBalance",
params=self._get_balance_params_factory(get_rng()),
),

@task(20)
def get_slot(self):
self.make_rpc_call(
method="getSlot",
),

@task(15)
def get_block_height(self):
self.make_rpc_call(
method="getBlockHeight",
),

@task(5)
@tag("get-program-accounts")
def get_program_accounts(self):
self.make_rpc_call(
method="getProgramAccounts",
params=[
"SharkXwkS3h24fJ2LZvgG5tPbsH3BKQYuAtKdqskf1f",
{"encoding": "base64", "commitment": "confirmed"},
],
),

@task(4)
def get_signature_statuses(self):
self.make_rpc_call(
method="getSignatureStatuses",
params=self._get_signature_statuses_params_factory(get_rng()),
),

@task(3)
def get_recent_blockhash(self):
self.make_rpc_call(
method="getRecentBlockhash",
),

@task(2)
def get_blocks(self):
self.make_rpc_call(
method="getBlocks",
params=self._get_blocks_params_factory(get_rng()),
),

@task(2)
def get_epoch_info(self):
self.make_rpc_call(
method="getEpochInfo",
),

@task(2)
def get_confirmed_signatures_for_address2(self):
self.make_rpc_call(
method="getConfirmedSignaturesForAddress2",
params=self._get_confirmed_signatures_for_address2_params_factory(get_rng()),
),
tasks = assign_tasks(
{
SolanaMethods.get_account_info_task: 1000,
SolanaMethods.get_block_task: 175,
SolanaMethods.get_token_accounts_by_owner_task: 150,
SolanaMethods.get_multiple_accounts_task: 150,
SolanaMethods.get_transaction_task: 130,
SolanaMethods.get_signatures_for_address_task: 75,
SolanaMethods.get_latest_blockhash_task: 75,
SolanaMethods.get_balance_task: 75,
SolanaMethods.get_slot_task: 20,
SolanaMethods.get_block_height_task: 15,
SolanaMethods.get_block_time_task: 15,
SolanaMethods.get_program_accounts_task: 5,
SolanaMethods.get_signature_statuses_task: 4,
SolanaMethods.get_blocks_task: 2,
SolanaMethods.get_epoch_info_task: 2,
}
)
13 changes: 13 additions & 0 deletions chainbench/test_data/solana.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,16 @@ def get_random_account(self, rng: RNG | None = None) -> Account:
if rng is None:
rng = get_rng()
return self.get_random_block(rng).get_random_account(rng)

@staticmethod
def get_random_token_address(self, rng: RNG | None = None) -> Account:
if rng is None:
rng = get_rng()
token_addresses = [
"z3dn17yLaGMKffVogeFHQ9zWVcXgqgf3PQnDsNs2g6M", # Oxygen Protocol
"2cZv8HrgcWSvC6n1uEiS48cEQGb1d3fiowP2rpa4wBL9", # ACF Game
"5fTwKZP2AK39LtFN9Ayppu6hdCVKfMGVm79F2EgHCtsi", # WHEYO
"NeonTjSjsuo3rexg9o6vHuMXw62f9V7zvmu8M8Zut44", # Neon EVM
"8BMzMi2XxZn9afRaMx5Z6fauk9foHXqV5cLTCYWRcVje", # Staika
]
return rng.random.choice(token_addresses)
21 changes: 20 additions & 1 deletion chainbench/user/http.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,33 @@
import logging
import typing as t

from locust import FastHttpUser
from locust import FastHttpUser, TaskSet
from locust.contrib.fasthttp import ResponseContextManager

from chainbench.test_data import TestData
from chainbench.util.rng import RNGManager
from chainbench.util.rpc import generate_request


def assign_tasks(
tasks: dict[t.Callable | TaskSet, int] | list[t.Callable | TaskSet | tuple[t.Callable | TaskSet, int]]
) -> list[t.Callable | TaskSet]:
new_tasks: list[t.Callable | TaskSet] = []
if isinstance(tasks, dict):
tasks = list(tasks.items())

if isinstance(tasks, list):
for task in tasks:
if isinstance(task, tuple):
task, count = task
for _ in range(count):
new_tasks.append(task)
else:
new_tasks.append(task)

return new_tasks


class HttpUser(FastHttpUser):
"""Extension of FastHttpUser for Chainbench."""

Expand Down
5 changes: 4 additions & 1 deletion chainbench/user/methods/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,22 @@
from .common import get_subclass_functions
from .ethereum import EthBeaconMethods
from .evm import EvmMethods
from .solana import SolanaMethods

__all__ = [
"EthBeaconMethods",
"EvmMethods",
"SolanaMethods",
"get_subclass_functions",
"all_method_classes",
"all_methods",
]


all_method_classes: list[Type[EthBeaconMethods | EvmMethods]] = [
all_method_classes: list[Type[EthBeaconMethods | EvmMethods | SolanaMethods]] = [
EthBeaconMethods,
EvmMethods,
SolanaMethods,
]


Expand Down
Loading