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

Scenarios for PR 6114 #27

Merged
merged 5 commits into from
Apr 29, 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
16 changes: 16 additions & 0 deletions testing-suite/staking-v4/caching.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import requests
from config import DEFAULT_PROXY
from chain_commander import add_blocks
import time


def force_reset_validator_statistics():
route = f"{DEFAULT_PROXY}/simulator/force-reset-validator-statistics"
mariusmihaic marked this conversation as resolved.
Show resolved Hide resolved
response = requests.post(route)
response.raise_for_status()

# add an extra block
add_blocks(1)

# wait 1 sec
time.sleep(1)
63 changes: 53 additions & 10 deletions testing-suite/staking-v4/chain_commander.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
import json

from config import *
from get_info import *
from network_provider.get_transaction_info import get_status_of_tx
from constants import *
import time
from core.validatorKey import ValidatorKey


def send_egld_to_address(egld_amount, erd_address):
Expand All @@ -22,12 +23,24 @@ def send_egld_to_address(egld_amount, erd_address):


def add_blocks(nr_of_blocks):
req = requests.post(f"{DEFAULT_PROXY}/simulator/generate-blocks/{nr_of_blocks}")
return req.text
response = requests.post(f"{DEFAULT_PROXY}/simulator/generate-blocks/{nr_of_blocks}")
response.raise_for_status()
return response.text


def get_block() -> int:
response = requests.get(f"{DEFAULT_PROXY}/network/status/0")
parsed = response.json()

general_data = parsed.get("data")
general_status = general_data.get("status")
nonce = general_status.get("erd_nonce")
mariusmihaic marked this conversation as resolved.
Show resolved Hide resolved
return nonce


def add_blocks_until_epoch_reached(epoch_to_be_reached: int):
req = requests.post(f"{DEFAULT_PROXY}/simulator/generate-blocks-until-epoch-reached/{str(epoch_to_be_reached)}")
add_blocks(1)
return req.text


Expand Down Expand Up @@ -61,14 +74,11 @@ def is_chain_online() -> bool:
return flag


def force_reset_validator_statistics():
req = requests.post(f"{DEFAULT_PROXY}/simulator/force-reset-validator-statistics")
print(req.text)
def add_key(keys: list[ValidatorKey]) -> str:
private_keys = []
for key in keys:
private_keys.append(key.get_private_key())

return req.text


def add_key(private_keys: list) -> str:
post_body = {
"privateKeysBase64": private_keys
}
Expand All @@ -77,3 +87,36 @@ def add_key(private_keys: list) -> str:
req = requests.post(f"{DEFAULT_PROXY}/simulator/add-keys", data=json_structure)

return req.text


def add_blocks_until_key_eligible(keys: list[ValidatorKey]) -> ValidatorKey:
mariusmihaic marked this conversation as resolved.
Show resolved Hide resolved
flag = False
while not flag:
for key in keys:
if key.get_state() == "eligible":
eligible_key = key
print("eligible key found")
flag = True

else:
print("no eligible key found , moving to next epoch...")
current_epoch = proxy_default.get_network_status().epoch_number
add_blocks_until_epoch_reached(current_epoch+1)
add_blocks(3)
mariusmihaic marked this conversation as resolved.
Show resolved Hide resolved

return eligible_key


def add_blocks_until_last_block_of_current_epoch() -> str:
response = requests.get(f"{DEFAULT_PROXY}/network/status/4294967295")
response.raise_for_status()
parsed = response.json()

general_data = parsed.get("data")
status = general_data.get("status")
passed_nonces = status.get("erd_nonces_passed_in_current_epoch")

blocks_to_be_added = rounds_per_epoch - passed_nonces
response_from_add_blocks = add_blocks(blocks_to_be_added)
return response_from_add_blocks

5 changes: 5 additions & 0 deletions testing-suite/staking-v4/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

DEFAULT_PROXY = PROXY_CHAIN_SIMULATOR

# TEMP
OBSERVER_META = "http://localhost:55802"
mariusmihaic marked this conversation as resolved.
Show resolved Hide resolved

try:
proxy_default = ProxyNetworkProvider(DEFAULT_PROXY)
except:
Expand All @@ -24,5 +27,7 @@
num_validators_meta = "10"
num_waiting_validators_per_shard = "6"
num_waiting_validators_meta = "6"
# real config after staking v4 full activation: eligible = 10 *4 , waiting = (6-2) *4, qualified = 2*4
# qualified nodes from auction will stay in wiating 2 epochs

rounds_per_epoch = "50"
47 changes: 34 additions & 13 deletions testing-suite/staking-v4/core/validatorKey.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import requests

import time
from core.wallet import *
from pathlib import Path
from helpers import *
from get_info import *
from constants import *
from chain_commander import *
from caching import force_reset_validator_statistics
from network_provider.get_validator_info import get_bls_key_status
from network_provider.get_validator_info import get_owner
from config import DEFAULT_PROXY, OBSERVER_META


class ValidatorKey:
Expand All @@ -25,35 +25,56 @@ def public_address(self) -> str:
return address

# is using vm-query with "getBlsKeysStatus" function
def get_status(self, owner_address: str) -> str:
def get_status(self, owner_address: str):
owner_address = Address.from_bech32(owner_address).to_hex()
key_status_pair = get_bls_key_status([owner_address])
if key_status_pair is None:
return "no bls keys on this owner"
return None
for key, status in key_status_pair.items():
if key == self.public_address():
return status

# is using /validator/statistics route
def get_state(self) -> str:
def get_state(self):
force_reset_validator_statistics()

# sometimes it needs a second until cache is resetting
time.sleep(1)

response = requests.get(f"{DEFAULT_PROXY}/validator/statistics")
response = requests.get(f"{OBSERVER_META}/validator/statistics")
response.raise_for_status()
parsed = response.json()

general_data = parsed.get("data")
general_statistics = general_data.get("statistics")
key_data = general_statistics.get(self.public_address())

if key_data is None:
return "Key not present in validator/statistics"
return None
else:
status = key_data.get("validatorStatus")
return status

# is using /validator/auction
def get_auction_state(self):
force_reset_validator_statistics()

response = requests.get(f"{OBSERVER_META}/validator/auction")
response.raise_for_status()
parsed = response.json()

general_data = parsed.get("data")
auction_list_data = general_data.get("auctionList")

for list in auction_list_data:
nodes_lists = list.get("nodes")
for node_list in nodes_lists:
if node_list.get("blsKey") == self.public_address():
mariusmihaic marked this conversation as resolved.
Show resolved Hide resolved
state = node_list.get("qualified")
if state:
return "qualified"
else:
return "unqualified"
else:
return None

# using getOwner vm-query
def belongs_to(self, address: str) -> bool:
owner = get_owner([self.public_address()])
Expand Down
6 changes: 1 addition & 5 deletions testing-suite/staking-v4/core/wallet.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
from pathlib import Path

from config import *
import requests
import json
from multiversx_sdk_network_providers import ProxyNetworkProvider
from multiversx_sdk_wallet import UserSigner
from multiversx_sdk_core import Address
from multiversx_sdk_network_providers import accounts
from helpers import *
from constants import *


class Wallet:
Expand Down
1 change: 0 additions & 1 deletion testing-suite/staking-v4/delegation.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from multiversx_sdk_core.transaction import TransactionComputer
from multiversx_sdk_network_providers import ProxyNetworkProvider
from multiversx_sdk_wallet import UserSigner
from get_info import *
from config import *
from helpers import *
from core.wallet import *
Expand Down
23 changes: 23 additions & 0 deletions testing-suite/staking-v4/network_provider/get_delegation_info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import requests
from config import DEFAULT_PROXY
from helpers import base64_to_hex
from multiversx_sdk_core import Address


def get_delegation_contract_address_from_tx(tx_hash):
response = requests.get(f"{DEFAULT_PROXY}/transaction/{tx_hash}?withResults=True")
response.raise_for_status()
parsed = response.json()

general_data = parsed.get("data")
transaction_data = general_data.get("transaction")
logs_data = transaction_data.get("logs")
events_data = logs_data.get("events")
first_set_of_events = events_data[0]
topics = first_set_of_events.get("topics")
delegation_contract_address = topics[1]

delegation_contract_address = base64_to_hex(delegation_contract_address)
delegation_contract_address = Address.from_hex(delegation_contract_address, "erd").to_bech32()

return delegation_contract_address
28 changes: 28 additions & 0 deletions testing-suite/staking-v4/network_provider/get_staking_info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import requests
import json
from multiversx_sdk_core import Address
from constants import VALIDATOR_CONTRACT
from config import DEFAULT_PROXY
from helpers import base64_to_string


def get_total_staked(owner: str):
address_in_hex = Address.from_bech32(owner).to_hex()
post_body = {
"scAddress": VALIDATOR_CONTRACT,
"funcName": "getTotalStaked",
"args": [address_in_hex]
}

json_structure = json.dumps(post_body)
response = requests.post(f"{DEFAULT_PROXY}/vm-values/query", data=json_structure)
response.raise_for_status()
parsed = response.json()

general_data = parsed.get("data")
tx_response_data = general_data.get("data")
total_staked_list = tx_response_data.get("returnData")
total_staked = total_staked_list[0]

total_staked = base64_to_string(total_staked)
return total_staked
33 changes: 33 additions & 0 deletions testing-suite/staking-v4/network_provider/get_transaction_info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

import requests
from config import DEFAULT_PROXY
from helpers import string_to_base64


def get_status_of_tx(tx_hash: str) -> str:
response = requests.get(f"{DEFAULT_PROXY}/transaction/{tx_hash}/process-status")
response.raise_for_status()
parsed = response.json()

if "transaction not found" in response.text:
return "expired"

general_data = parsed.get("data")
status = general_data.get("status")
return status


def check_if_error_is_present_in_tx(error, tx_hash) -> bool:
flag = False
error_bytes = string_to_base64(error)

response = requests.get(f"{DEFAULT_PROXY}/transaction/{tx_hash}?withResults=True")
response.raise_for_status()

if error_bytes.decode() in response.text:
flag = True

if error in response.text:
flag = True

return error_bytes.decode() in response.text or error in response.text
Loading
Loading