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

NDEV-342: Platform synthetic performance test (do not merge) #78

Open
wants to merge 75 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
a7d2bf9
NDEV-342: Add infra
Aug 23, 2022
9baef8a
NDEV-342: Infra small fixes
Aug 24, 2022
7ee4bc3
NDEV-342: Added neon-cli wrapper
Aug 24, 2022
738caac
NDEV-342: Fix some dependensys
Aug 25, 2022
7044e7d
NDEV-342: Fix SOL client
Aug 26, 2022
4a5003f
NDEV-342: Fix SOL client
Aug 29, 2022
17b1f81
NDEV-342: Added methods to solana client
Aug 30, 2022
bf95f53
NDEV-342: Added methods to solana client
Aug 30, 2022
0e5ac6d
NDEV-342: Added methods to solana client
Aug 30, 2022
32f861d
NDEV-342: Small fixes
Sep 7, 2022
e280e0f
NDEV-342: Fix sol client
Sep 8, 2022
3da30ef
NDEV-342: Fix sol client
Sep 8, 2022
45ea11a
NDEV-342: Some fixes
Sep 9, 2022
d79ed7c
NDEV-342: Some fixes
Sep 9, 2022
206e433
NDEV-342: Small fixes
Sep 12, 2022
d4c710f
* use new instruction
gigimon Sep 13, 2022
4e46d62
* fix
gigimon Sep 13, 2022
261dff8
Merge remote-tracking branch 'origin/develop' into feature/NDEV-342
Sep 14, 2022
274b3b4
NDEV-342: Refactoring
Sep 14, 2022
15ced6b
NDEV-342: Add task to synthetic tes
Sep 15, 2022
700ef77
NDEV-342: Fix task
Sep 15, 2022
a5ad182
NDEV-342: Fix waiting transaction confirmation
Sep 16, 2022
83d27f0
NDEV-342: Small fix
Sep 16, 2022
fd7574e
NDEV-342: Small fix
Sep 16, 2022
a6e2055
NDEV-342: Small fix
Sep 16, 2022
91fc857
Merge remote-tracking branch 'origin/develop' into feature/NDEV-342
Sep 16, 2022
d3183c3
* don't use preflight
gigimon Sep 16, 2022
8846bdb
NDEV-342: Small fix
Sep 16, 2022
a4825dd
Merge remote-tracking branch 'origin/develop' into feature/NDEV-342
Sep 16, 2022
a66da53
Merge remote-tracking branch 'origin/feature/NDEV-342' into feature/N…
Sep 16, 2022
bb6c849
NDEV-342: Small fix
Sep 16, 2022
a64dc1c
NDEV-342: Small fix
Sep 16, 2022
19c8742
NDEV-342: Fix nonce
Sep 16, 2022
f2613e7
* try cache for recent blockhash
gigimon Sep 16, 2022
e619420
* try cache for recent blockhash
gigimon Sep 16, 2022
54b84da
* try cache for recent blockhash
gigimon Sep 16, 2022
1033c12
* try to use random sender and receiver
gigimon Sep 16, 2022
d20e2a5
* try to use random sender and receiver
gigimon Sep 16, 2022
d91d086
* try to use random sender and receiver
gigimon Sep 16, 2022
c0b5be7
* try to use random sender and receiver
gigimon Sep 16, 2022
5a5e8a4
* try to use random sender and receiver
gigimon Sep 16, 2022
c6a65d6
* try to use random sender and receiver
gigimon Sep 16, 2022
78574c7
* try to use random sender and receiver
gigimon Sep 16, 2022
4422896
* experiments
gigimon Sep 19, 2022
3fb8519
* experiments
gigimon Sep 19, 2022
5aa0f59
* wip
gigimon Sep 20, 2022
91af1f6
* wip
gigimon Sep 20, 2022
99a49f1
* wip
gigimon Sep 20, 2022
30988b3
* wip
gigimon Sep 20, 2022
1adbfc4
* wip
gigimon Sep 22, 2022
31d2295
* wip
gigimon Sep 22, 2022
2ba4fc4
* add more op keys
gigimon Sep 22, 2022
6068894
* move keys
gigimon Sep 22, 2022
2513104
* move keys
gigimon Sep 22, 2022
7ef3081
* return envs
gigimon Sep 22, 2022
766c0e0
* wip
gigimon Sep 26, 2022
f40bee7
* add fire event
gigimon Oct 4, 2022
323b296
* add new script
gigimon Oct 4, 2022
b0bd410
* fixes for new accounts
gigimon Oct 5, 2022
4b37a12
* use thread to generate users
gigimon Oct 26, 2022
21a9aa4
* more keys
gigimon Oct 26, 2022
fb6fb41
* more keys
gigimon Oct 26, 2022
ee69ad8
* add threads for operator
gigimon Oct 27, 2022
e2bce70
* add threads for operator
gigimon Oct 27, 2022
8ec3c23
* add threads for operator
gigimon Oct 27, 2022
3c5e79c
* add threads for operator
gigimon Oct 27, 2022
ce76305
* add threads for operator
gigimon Oct 27, 2022
a2102bc
* add threads for operator
gigimon Oct 27, 2022
902b730
* new treasury generate
gigimon Oct 28, 2022
045b5d2
* add more op keys
gigimon Oct 28, 2022
98ca261
* add more op keys
gigimon Oct 31, 2022
0fd898a
* fixes
gigimon Oct 31, 2022
2fca466
use fasthttp client
gigimon Nov 1, 2022
fe0c97c
* experiments with molotov
gigimon Nov 1, 2022
b62356a
* clean code
gigimon Nov 2, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
8 changes: 8 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"python.defaultInterpreterPath": "/Users/gigimon/workspaces/neon/venv/bin/python",
"python.testing.pytestArgs": [
"."
],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true
}
4 changes: 4 additions & 0 deletions clickfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,14 @@
import subprocess
import sys
import typing as tp
import platform
from collections import defaultdict
from multiprocessing.dummy import Pool
from urllib.parse import urlparse

from deploy.infra.utils import env
from deploy.infra.utils import docker as docker_utils

import requests

from deploy.infra.utils import docker as docker_utils
Expand Down
10 changes: 10 additions & 0 deletions deploy/infra/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,19 @@ RUN apt-get update && apt-get install -qy --no-install-recommends ${PIP_BUILD_DE

# Install PIP requirements
RUN python3 -m ensurepip \
<<<<<<< HEAD
&& pip install -U --upgrade-strategy=only-if-needed wheel pip==21.1 pip-tools==6.2.0 \
=======
&& pip install -U --upgrade-strategy=only-if-needed wheel pip pip-tools \
>>>>>>> b0e94e36f104a0bd63a5d11c9b3b9c45772e8081
&& pip install --upgrade \
-r ${HOME_DIR}/deploy/requirements/prod.txt \
-r ${HOME_DIR}/deploy/requirements/devel.txt \
-r ${HOME_DIR}/deploy/requirements/ui.txt \
<<<<<<< HEAD
=======
#-r ${HOME_DIR}/deploy/requirements/nodeps.txt \
>>>>>>> b0e94e36f104a0bd63a5d11c9b3b9c45772e8081
--src=/usr/local/lib/python3.8/site-packages ;

# Fixes for ctypes.cdll.LoadLibrary:
Expand All @@ -47,11 +54,14 @@ RUN python3 -m ensurepip \
RUN [ ! -L "/usr/lib/x86_64-linux-gnu/libssh2.so" ] || ln -sf libssh2.so.1 /usr/lib/x86_64-linux-gnu/libssh2.so


<<<<<<< HEAD
=======
# Install tfenv fo terraform using in devbox
RUN git clone --depth=1 https://github.com/tfutils/tfenv.git ~/.tfenv \
&& echo 'export PATH="$HOME/.tfenv/bin:$PATH"' >> ~/.bash_profile \
&& ln -s ~/.tfenv/bin/* /usr/local/bin

>>>>>>> b0e94e36f104a0bd63a5d11c9b3b9c45772e8081
# Cleanup:
## Git cache saves ~ 1min on pip-sync
RUN find /usr/local/lib/python3.8/site-packages -name .git | xargs rm -rf \
Expand Down
6 changes: 5 additions & 1 deletion deploy/infra/devbox/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
*.bash_history
<<<<<<< HEAD
*bash_history
=======
*.bash_history
>>>>>>> b0e94e36f104a0bd63a5d11c9b3b9c45772e8081
2 changes: 1 addition & 1 deletion deploy/requirements/nodeps.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# this file for packages which has conflicts with
web3==5.26.0
web3==5.26.0
63 changes: 37 additions & 26 deletions integration/tests/basic/test_rpc_calls.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import time
import typing as tp
from enum import Enum

Expand All @@ -7,13 +6,11 @@
import sha3
import web3

from integration.tests.basic.helpers import rpc_checks
from integration.tests.basic.helpers.assert_message import AssertMessage
from integration.tests.basic.helpers.basic import BaseMixin
from integration.tests.basic.helpers import rpc_checks
from utils import helpers
from utils.consts import Unit
from utils.helpers import gen_hash_of_block
from ui.libs import try_until

"""
12. Verify implemented rpc calls work
Expand Down Expand Up @@ -162,7 +159,7 @@ def test_eth_gas_price(self, params: tp.Union[str, None], raises: bool):
(Tag.EARLIEST, Tag.EARLIEST),
(Tag.EARLIEST, Tag.PENDING),
(Tag.EARLIEST, Tag.LATEST),
(Tag.EARLIEST, None)
(Tag.EARLIEST, None),
],
)
def test_eth_get_logs_via_tags(self, tag1: Tag, tag2: Tag, send_erc20: tp.Any):
Expand Down Expand Up @@ -232,7 +229,7 @@ def test_net_version(self, params: tp.Union[str, None], raises: bool):
else:
assert "error" not in response
assert (
int(response["result"]) == self.web3_client._chain_id
int(response["result"]) == self.web3_client._chain_id
), f"Invalid response result {response['result']}"

@pytest.mark.parametrize(
Expand Down Expand Up @@ -283,22 +280,30 @@ def test_rpc_call_eth_get_transaction_receipt(self):
assert "error" not in response
assert "result" in response, AssertMessage.DOES_NOT_CONTAIN_RESULT
result = response["result"]
expected_hex_fields = ['transactionHash', 'transactionIndex', 'blockNumber', 'blockHash', 'cumulativeGasUsed',
'gasUsed', 'logsBloom', 'status']
expected_hex_fields = [
"transactionHash",
"transactionIndex",
"blockNumber",
"blockHash",
"cumulativeGasUsed",
"gasUsed",
"logsBloom",
"status",
]
for field in expected_hex_fields:
assert rpc_checks.is_hex(result[field])
assert result["status"] == '0x1', "Transaction status must be 0x1"
assert result["status"] == "0x1", "Transaction status must be 0x1"
assert result["transactionHash"] == transaction_hash
assert result["blockHash"] == tx_receipt.blockHash.hex()
assert result["from"].upper() == tx_receipt['from'].upper()
assert result["to"].upper() == tx_receipt['to'].upper()
assert result["from"].upper() == tx_receipt["from"].upper()
assert result["to"].upper() == tx_receipt["to"].upper()
assert result["contractAddress"] is None
assert result["logs"] == []

def test_rpc_call_eth_get_transaction_receipt_when_hash_doesnt_exist(self):
"""Verify implemented rpc calls work eth_getTransactionReceipt when transaction hash doesn't exist"""
response = self.proxy_api.send_rpc(method="eth_getTransactionReceipt", params=gen_hash_of_block(32))
assert response['result'] is None, "Result should be None"
assert response["result"] is None, "Result should be None"

def test_rpc_call_eth_get_transaction_receipt_with_incorrect_hash(self):
"""Verify implemented rpc calls work eth_getTransactionReceipt when transaction hash is not correct"""
Expand All @@ -316,10 +321,14 @@ def test_eth_get_block_by_hash(self, full_trx: bool):
rpc_checks.assert_block_fields(response, full_trx, tx_receipt)

@pytest.mark.xfail(reason="NDEV-605")
@pytest.mark.parametrize("hash, full_trx, msg",
[(gen_hash_of_block(31), False, "Key not found in database"),
(gen_hash_of_block(32), True, "Key not found in database"),
("bad_hash", True, "Invalid `blockNumber`: \"bad_hash\"")])
@pytest.mark.parametrize(
"hash, full_trx, msg",
[
(gen_hash_of_block(31), False, "Key not found in database"),
(gen_hash_of_block(32), True, "Key not found in database"),
("bad_hash", True, 'Invalid `blockNumber`: "bad_hash"'),
],
)
def test_eth_get_block_by_hash_with_incorrect_hash(self, hash, full_trx, msg):
"""Verify implemented rpc calls work eth_getBlockByHash with incorrect hash"""
params = [hash, full_trx]
Expand All @@ -333,21 +342,23 @@ def test_eth_get_block_by_hash_with_incorrect_hash(self, hash, full_trx, msg):
def test_eth_get_block_by_number_via_numbers(self, full_trx):
"""Verify implemented rpc calls work eth_getBlockByNumber"""
tx_receipt = self.send_neon(self.sender_account, self.recipient_account, 10)
response = self.proxy_api.send_rpc(method="eth_getBlockByNumber",
params=[tx_receipt.blockNumber, full_trx])
response = self.proxy_api.send_rpc(method="eth_getBlockByNumber", params=[tx_receipt.blockNumber, full_trx])
rpc_checks.assert_block_fields(response, full_trx, tx_receipt)

@pytest.mark.xfail(reason="NDEV-605")
@pytest.mark.parametrize("number, full_trx, msg",
[(gen_hash_of_block(31), False, "Key not found in database"),
(1, True, "Key not found in database"),
(1, True, "Invalid `blockNumber`: \"1\""),
("bad_tag", True, "Invalid `blockNumber`: \"bad_hash\"")])
@pytest.mark.parametrize(
"number, full_trx, msg",
[
(gen_hash_of_block(31), False, "Key not found in database"),
(1, True, "Key not found in database"),
(1, True, 'Invalid `blockNumber`: "1"'),
("bad_tag", True, 'Invalid `blockNumber`: "bad_hash"'),
],
)
def test_eth_get_block_by_number_with_incorrect_data(self, number, full_trx, msg):
"""Verify implemented rpc calls work eth_getBlockByNumber"""
tx_receipt = self.send_neon(self.sender_account, self.recipient_account, 10)
response = self.proxy_api.send_rpc(method="eth_getBlockByNumber",
params=[tx_receipt.blockNumber, full_trx])
response = self.proxy_api.send_rpc(method="eth_getBlockByNumber", params=[tx_receipt.blockNumber, full_trx])
rpc_checks.assert_block_fields(response, full_trx, tx_receipt)
assert "error" in response, "Error not in response"
assert response["error"]["code"] == -32000
Expand Down Expand Up @@ -544,7 +555,7 @@ def constructor_args(self, request: tp.Any) -> tp.List[int]:

@pytest.fixture(params=["BigGasFactory1", "BigGasFactory2"])
def deploy_big_gas_requirements_contract(
self, request: tp.Any, constructor_args: tp.List[int]
self, request: tp.Any, constructor_args: tp.List[int]
) -> "web3._utils.datatypes.Contract":
"""Deploy contracts"""
self.account = self.sender_account
Expand Down
4 changes: 4 additions & 0 deletions loadtesting/proxy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# coding: utf-8
"""
<<<<<<< HEAD
Created on 2022-08-18
=======
Created on 2022-09-06
>>>>>>> b0e94e36f104a0bd63a5d11c9b3b9c45772e8081
@author: Eugeny Kurkovich
"""
5 changes: 5 additions & 0 deletions loadtesting/synthetic/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# coding: utf-8
"""
Created on 2022-08-18
@author: Eugeny Kurkovich
"""
22 changes: 22 additions & 0 deletions loadtesting/synthetic/get_cu.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import os
import re
from solana.rpc.api import Client as SolanaClient


client = SolanaClient(os.environ.get("SOLANA_URL"))

block_height = client.get_slot()["result"]

for num in range(block_height-32, block_height):
block = client.get_block(num)["result"]

cu = 0

for tr in block["transactions"]:
res = re.findall(r"consumed (\d+) of (:?\d+) compute units", "".join(tr["meta"]["logMessages"]))
if not res:
continue
cu += int(res[0][0])
print(f"Transactions in block {num}: ", len(block["transactions"]))
print("CU: ", cu)

114 changes: 114 additions & 0 deletions loadtesting/synthetic/helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# coding: utf-8
"""
Created on 2022-08-29
@author: Eugeny Kurkovich
"""
import typing as tp
from dataclasses import dataclass
from hashlib import sha256

from construct import Bytes, Int8ul, Struct, Int32ul
from eth_keys import keys as eth_keys
from solana.publickey import PublicKey
from solana.rpc import commitment
from solana.transaction import Transaction, TransactionInstruction

ACCOUNT_INFO_LAYOUT = Struct(
"type" / Int8ul,
"ether" / Bytes(20),
"nonce" / Int8ul,
"tx_count" / Bytes(8),
"balance" / Bytes(32),
"generation" / Int32ul,
"code_size" / Int32ul,
"is_rw_blocked" / Int8ul,
)


DEFAULT_UNITS = 500 * 1000
DEFAULT_HEAP_FRAME = 256 * 1024
DEFAULT_ADDITIONAL_FEE = 0
COMPUTE_BUDGET_ID: PublicKey = PublicKey("ComputeBudget111111111111111111111111111111")
SYSTEM_ADDRESS = "11111111111111111111111111111111"


@dataclass
class AccountInfo:
ether: eth_keys.PublicKey
trx_count: int

@staticmethod
def from_bytes(data: bytes):
cont = ACCOUNT_INFO_LAYOUT.parse(data)
return AccountInfo(cont.ether, cont.tx_count)


@dataclass
class SOLCommitmentState:
"""Bank states to solana query"""

CONFIRMED: str = commitment.Confirmed
FINALIZED: str = commitment.Finalized
PROCESSED: str = commitment.Processed


@dataclass
class TreasuryPoolBases:
"""Collateral pool base address"""

DEVNET: str = "7SBdHNeF9FFYySEoszpjZXXQsAiwa5Lzpsz6nUJWusEx"
NIGHT_STAND: str = "4sW3SZDJB7qXUyCYKA7pFL8eCTfm3REr8oSiKkww7MaT"

@classmethod
def get_by_network(cls, network: str) -> str:
"""Get collateral pool base address"""
return getattr(cls, network.replace("-", "_").upper(), cls.NIGHT_STAND)


@dataclass
class TreasuryPool:
index: int
account: PublicKey
buffer: bytes


class ComputeBudget:
@staticmethod
def request_units(units, additional_fee):
return TransactionInstruction(
program_id=COMPUTE_BUDGET_ID,
keys=[],
data=bytes.fromhex("00") + units.to_bytes(4, "little") + additional_fee.to_bytes(4, "little"),
)

@staticmethod
def request_heap_frame(heap_frame):
return TransactionInstruction(
program_id=COMPUTE_BUDGET_ID, keys=[], data=bytes.fromhex("01") + heap_frame.to_bytes(4, "little")
)


class TransactionWithComputeBudget(Transaction):
def __init__(
self, units=DEFAULT_UNITS, additional_fee=DEFAULT_ADDITIONAL_FEE, heap_frame=DEFAULT_HEAP_FRAME, *args, **kwargs
):
super().__init__(*args, **kwargs)
if units:
self.instructions.append(ComputeBudget.request_units(units, additional_fee))
if heap_frame:
self.instructions.append(ComputeBudget.request_heap_frame(heap_frame))


def gen_account_with_seed(base, seed, program) -> PublicKey:
return PublicKey(sha256(bytes(base) + bytes(seed, "utf8") + bytes(program)).digest())


def create_treasury_pool_address(
network: str, loader_id: str, collateral_pool_index: tp.Optional[int] = 2
) -> TreasuryPool:
"""Create treasury pool address"""
collateral_seed_prefix = "treasury_pool"
index_buf = collateral_pool_index.to_bytes(4, "little")
address, bump = PublicKey.find_program_address([bytes(collateral_seed_prefix, "utf8"), index_buf], PublicKey(loader_id))
# address = gen_account_with_seed(PublicKey(TreasuryPoolBases.get_by_network(network)), seed, PublicKey(loader_id))
return TreasuryPool(collateral_pool_index, address, index_buf)
Loading