Skip to content

Commit

Permalink
Merge pull request #27 from multiversx/tests-for-pr-6114
Browse files Browse the repository at this point in the history
Scenarios for PR 6114
  • Loading branch information
gabi-vuls authored Apr 29, 2024
2 parents 08e7a3d + 131bbb5 commit f33cc17
Show file tree
Hide file tree
Showing 15 changed files with 479 additions and 115 deletions.
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"
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")
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:
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)

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"

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():
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

0 comments on commit f33cc17

Please sign in to comment.