mirror of
https://github.com/planetmint/planetmint.git
synced 2025-06-07 14:46:38 +00:00
373 integration of the dataaccessor singleton (#389)
* initial singleton usage Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * passing all tests Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * blackified Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> * aggretated code into helper functions Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com> --------- Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com>
This commit is contained in:
parent
884c3cc32b
commit
5c4923dbd6
40
docker-compose-aio.yml
Normal file
40
docker-compose-aio.yml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# Copyright © 2020 Interplanetary Database Association e.V.,
|
||||||
|
# Planetmint and IPDB software contributors.
|
||||||
|
# SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0)
|
||||||
|
# Code is Apache-2.0 and docs are CC-BY-4.0
|
||||||
|
|
||||||
|
version: '2.2'
|
||||||
|
|
||||||
|
services:
|
||||||
|
planetmint-all-in-one:
|
||||||
|
image: planetmint/planetmint-aio:latest
|
||||||
|
expose:
|
||||||
|
- "22"
|
||||||
|
- "9984"
|
||||||
|
- "9985"
|
||||||
|
- "26656"
|
||||||
|
- "26657"
|
||||||
|
- "26658"
|
||||||
|
command: ["/usr/src/app/scripts/pre-config-planetmint.sh", "/usr/src/app/scripts/all-in-one.bash"]
|
||||||
|
volumes:
|
||||||
|
- ./integration/scripts:/usr/src/app/scripts
|
||||||
|
- shared:/shared
|
||||||
|
scale: ${SCALE:-4}
|
||||||
|
|
||||||
|
test:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: integration/python/Dockerfile
|
||||||
|
depends_on:
|
||||||
|
- planetmint-all-in-one
|
||||||
|
command: ["/scripts/pre-config-test.sh", "/scripts/wait-for-planetmint.sh", "/scripts/test.sh", "pytest", "/src"]
|
||||||
|
environment:
|
||||||
|
SCALE: ${SCALE:-4}
|
||||||
|
volumes:
|
||||||
|
- ./integration/python/src:/src
|
||||||
|
- ./integration/scripts:/scripts
|
||||||
|
- ./integration/cli:/tests
|
||||||
|
- shared:/shared
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
shared:
|
@ -28,14 +28,14 @@ from planetmint.backend.models.output import Output
|
|||||||
from planetmint.model.dataaccessor import DataAccessor
|
from planetmint.model.dataaccessor import DataAccessor
|
||||||
from planetmint.config import Config
|
from planetmint.config import Config
|
||||||
from planetmint.config_utils import load_validation_plugin
|
from planetmint.config_utils import load_validation_plugin
|
||||||
|
from planetmint.utils.singleton import Singleton
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Validator:
|
class Validator:
|
||||||
def __init__(self, async_io: bool = False):
|
def __init__(self):
|
||||||
self.async_io = async_io
|
self.models = DataAccessor()
|
||||||
self.models = DataAccessor(async_io=async_io)
|
|
||||||
self.validation = Validator._get_validation_method()
|
self.validation = Validator._get_validation_method()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -269,7 +269,7 @@ class Validator:
|
|||||||
value as the `voting_power`
|
value as the `voting_power`
|
||||||
"""
|
"""
|
||||||
validators = {}
|
validators = {}
|
||||||
for validator in self.models.get_validators(height):
|
for validator in self.models.get_validators(height=height):
|
||||||
# NOTE: we assume that Tendermint encodes public key in base64
|
# NOTE: we assume that Tendermint encodes public key in base64
|
||||||
public_key = public_key_from_ed25519_key(key_from_base64(validator["public_key"]["value"]))
|
public_key = public_key_from_ed25519_key(key_from_base64(validator["public_key"]["value"]))
|
||||||
validators[public_key] = validator["voting_power"]
|
validators[public_key] = validator["voting_power"]
|
||||||
@ -493,7 +493,7 @@ class Validator:
|
|||||||
self.migrate_abci_chain()
|
self.migrate_abci_chain()
|
||||||
if election.operation == VALIDATOR_ELECTION:
|
if election.operation == VALIDATOR_ELECTION:
|
||||||
validator_updates = [election.assets[0].data]
|
validator_updates = [election.assets[0].data]
|
||||||
curr_validator_set = self.models.get_validators(new_height)
|
curr_validator_set = self.models.get_validators(height=new_height)
|
||||||
updated_validator_set = new_validator_set(curr_validator_set, validator_updates)
|
updated_validator_set = new_validator_set(curr_validator_set, validator_updates)
|
||||||
|
|
||||||
updated_validator_set = [v for v in updated_validator_set if v["voting_power"] > 0]
|
updated_validator_set = [v for v in updated_validator_set if v["voting_power"] > 0]
|
||||||
|
@ -64,7 +64,6 @@ class DBConnection(metaclass=DBSingleton):
|
|||||||
backend: str = None,
|
backend: str = None,
|
||||||
connection_timeout: int = None,
|
connection_timeout: int = None,
|
||||||
max_tries: int = None,
|
max_tries: int = None,
|
||||||
async_io: bool = False,
|
|
||||||
**kwargs
|
**kwargs
|
||||||
):
|
):
|
||||||
"""Create a new :class:`~.Connection` instance.
|
"""Create a new :class:`~.Connection` instance.
|
||||||
|
@ -407,11 +407,12 @@ def store_validator_set(conn, validators_update: dict):
|
|||||||
conn.connect().select(TARANT_TABLE_VALIDATOR_SETS, validators_update["height"], index="height", limit=1).data
|
conn.connect().select(TARANT_TABLE_VALIDATOR_SETS, validators_update["height"], index="height", limit=1).data
|
||||||
)
|
)
|
||||||
unique_id = uuid4().hex if _validator is None or len(_validator) == 0 else _validator[0][0]
|
unique_id = uuid4().hex if _validator is None or len(_validator) == 0 else _validator[0][0]
|
||||||
conn.connect().upsert(
|
result = conn.connect().upsert(
|
||||||
TARANT_TABLE_VALIDATOR_SETS,
|
TARANT_TABLE_VALIDATOR_SETS,
|
||||||
(unique_id, validators_update["height"], validators_update["validators"]),
|
(unique_id, validators_update["height"], validators_update["validators"]),
|
||||||
op_list=[("=", 1, validators_update["height"]), ("=", 2, validators_update["validators"])],
|
op_list=[("=", 1, validators_update["height"]), ("=", 2, validators_update["validators"])],
|
||||||
)
|
)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
@register_query(TarantoolDBConnection)
|
@register_query(TarantoolDBConnection)
|
||||||
|
@ -22,12 +22,19 @@ from planetmint.backend.models.output import Output
|
|||||||
from planetmint.backend.models.asset import Asset
|
from planetmint.backend.models.asset import Asset
|
||||||
from planetmint.backend.models.metadata import MetaData
|
from planetmint.backend.models.metadata import MetaData
|
||||||
from planetmint.backend.models.dbtransaction import DbTransaction
|
from planetmint.backend.models.dbtransaction import DbTransaction
|
||||||
|
from planetmint.utils.singleton import Singleton
|
||||||
|
|
||||||
|
|
||||||
class DataAccessor:
|
class DataAccessor(metaclass=Singleton):
|
||||||
def __init__(self, database_connection=None, async_io: bool = False):
|
def __init__(self, database_connection=None):
|
||||||
config_utils.autoconfigure()
|
config_utils.autoconfigure()
|
||||||
self.connection = database_connection if database_connection is not None else Connection(async_io=async_io)
|
self.connection = database_connection if database_connection is not None else Connection()
|
||||||
|
|
||||||
|
def close_connection(self):
|
||||||
|
self.connection.close()
|
||||||
|
|
||||||
|
def connect(self):
|
||||||
|
self.connection.connect()
|
||||||
|
|
||||||
def store_bulk_transactions(self, transactions):
|
def store_bulk_transactions(self, transactions):
|
||||||
txns = []
|
txns = []
|
||||||
@ -144,7 +151,7 @@ class DataAccessor:
|
|||||||
value as the `voting_power`
|
value as the `voting_power`
|
||||||
"""
|
"""
|
||||||
validators = {}
|
validators = {}
|
||||||
for validator in self.get_validators(height):
|
for validator in self.get_validators(height=height):
|
||||||
# NOTE: we assume that Tendermint encodes public key in base64
|
# NOTE: we assume that Tendermint encodes public key in base64
|
||||||
public_key = public_key_from_ed25519_key(key_from_base64(validator["public_key"]["value"]))
|
public_key = public_key_from_ed25519_key(key_from_base64(validator["public_key"]["value"]))
|
||||||
validators[public_key] = validator["voting_power"]
|
validators[public_key] = validator["voting_power"]
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[pytest]
|
[pytest]
|
||||||
testpaths = tests/
|
testpaths = tests/
|
||||||
norecursedirs = .* *.egg *.egg-info env* devenv* docs
|
norecursedirs = .* *.egg *.egg-info env* devenv* docs
|
||||||
addopts = -m "abci"
|
addopts = -m "not abci"
|
||||||
looponfailroots = planetmint tests
|
looponfailroots = planetmint tests
|
||||||
asyncio_mode = strict
|
asyncio_mode = strict
|
||||||
markers =
|
markers =
|
||||||
|
@ -157,14 +157,14 @@ def test_single_in_single_own_multiple_out_single_own_transfer(alice, b, user_pk
|
|||||||
)
|
)
|
||||||
tx_create_signed = tx_create.sign([alice.private_key])
|
tx_create_signed = tx_create.sign([alice.private_key])
|
||||||
|
|
||||||
|
b.models.store_bulk_transactions([tx_create_signed])
|
||||||
|
inputs = tx_create.to_inputs()
|
||||||
# TRANSFER
|
# TRANSFER
|
||||||
tx_transfer = Transfer.generate(
|
tx_transfer = Transfer.generate(
|
||||||
tx_create.to_inputs(), [([alice.public_key], 50), ([alice.public_key], 50)], asset_ids=[tx_create.id]
|
inputs, [([alice.public_key], 50), ([alice.public_key], 50)], asset_ids=[tx_create.id]
|
||||||
)
|
)
|
||||||
tx_transfer_signed = tx_transfer.sign([user_sk])
|
tx_transfer_signed = tx_transfer.sign([user_sk])
|
||||||
|
|
||||||
b.models.store_bulk_transactions([tx_create_signed])
|
|
||||||
|
|
||||||
assert b.validate_transaction(tx_transfer_signed) == tx_transfer_signed
|
assert b.validate_transaction(tx_transfer_signed) == tx_transfer_signed
|
||||||
assert len(tx_transfer_signed.outputs) == 2
|
assert len(tx_transfer_signed.outputs) == 2
|
||||||
assert tx_transfer_signed.outputs[0].amount == 50
|
assert tx_transfer_signed.outputs[0].amount == 50
|
||||||
|
@ -26,6 +26,103 @@ from planetmint.backend.connection import Connection
|
|||||||
from tests.utils import generate_election, generate_validators
|
from tests.utils import generate_election, generate_validators
|
||||||
|
|
||||||
|
|
||||||
|
def mock_get_validators(self, height):
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
"public_key": {
|
||||||
|
"value": "zL/DasvKulXZzhSNFwx4cLRXKkSM9GPK7Y0nZ4FEylM=",
|
||||||
|
"type": "ed25519-base64",
|
||||||
|
},
|
||||||
|
"voting_power": 10,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@patch("planetmint.commands.utils.start")
|
||||||
|
def test_main_entrypoint(mock_start):
|
||||||
|
from planetmint.commands.planetmint import main
|
||||||
|
from planetmint.model.dataaccessor import DataAccessor
|
||||||
|
|
||||||
|
da = DataAccessor
|
||||||
|
del da
|
||||||
|
main()
|
||||||
|
|
||||||
|
assert mock_start.called
|
||||||
|
|
||||||
|
|
||||||
|
# @pytest.mark.bdb
|
||||||
|
def test_chain_migration_election_show_shows_inconclusive(b_flushed, test_abci_rpc):
|
||||||
|
from tests.utils import flush_db
|
||||||
|
|
||||||
|
b = b_flushed
|
||||||
|
|
||||||
|
validators = generate_validators([1] * 4)
|
||||||
|
output = b.models.store_validator_set(1, [v["storage"] for v in validators])
|
||||||
|
|
||||||
|
public_key = validators[0]["public_key"]
|
||||||
|
private_key = validators[0]["private_key"]
|
||||||
|
voter_keys = [v["private_key"] for v in validators]
|
||||||
|
|
||||||
|
election, votes = generate_election(b, ChainMigrationElection, public_key, private_key, [{"data": {}}], voter_keys)
|
||||||
|
|
||||||
|
assert not run_election_show(Namespace(election_id=election.id), b)
|
||||||
|
|
||||||
|
b.process_block(1, [election])
|
||||||
|
b.models.store_bulk_transactions([election])
|
||||||
|
|
||||||
|
assert run_election_show(Namespace(election_id=election.id), b) == "status=ongoing"
|
||||||
|
|
||||||
|
b.models.store_block(Block(height=1, transactions=[], app_hash="")._asdict())
|
||||||
|
b.models.store_validator_set(2, [v["storage"] for v in validators])
|
||||||
|
|
||||||
|
assert run_election_show(Namespace(election_id=election.id), b) == "status=ongoing"
|
||||||
|
|
||||||
|
b.models.store_block(Block(height=2, transactions=[], app_hash="")._asdict())
|
||||||
|
# TODO insert yet another block here when upgrading to Tendermint 0.22.4.
|
||||||
|
|
||||||
|
assert run_election_show(Namespace(election_id=election.id), b) == "status=inconclusive"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.bdb
|
||||||
|
def test_chain_migration_election_show_shows_concluded(b_flushed):
|
||||||
|
b = b_flushed
|
||||||
|
validators = generate_validators([1] * 4)
|
||||||
|
b.models.store_validator_set(1, [v["storage"] for v in validators])
|
||||||
|
|
||||||
|
public_key = validators[0]["public_key"]
|
||||||
|
private_key = validators[0]["private_key"]
|
||||||
|
voter_keys = [v["private_key"] for v in validators]
|
||||||
|
|
||||||
|
election, votes = generate_election(b, ChainMigrationElection, public_key, private_key, [{"data": {}}], voter_keys)
|
||||||
|
|
||||||
|
assert not run_election_show(Namespace(election_id=election.id), b)
|
||||||
|
|
||||||
|
b.models.store_bulk_transactions([election])
|
||||||
|
b.process_block(1, [election])
|
||||||
|
|
||||||
|
assert run_election_show(Namespace(election_id=election.id), b) == "status=ongoing"
|
||||||
|
|
||||||
|
b.models.store_abci_chain(1, "chain-X")
|
||||||
|
b.models.store_block(Block(height=1, transactions=[v.id for v in votes], app_hash="last_app_hash")._asdict())
|
||||||
|
b.process_block(2, votes)
|
||||||
|
|
||||||
|
assert (
|
||||||
|
run_election_show(Namespace(election_id=election.id), b)
|
||||||
|
== f'''status=concluded
|
||||||
|
chain_id=chain-X-migrated-at-height-1
|
||||||
|
app_hash=last_app_hash
|
||||||
|
validators=[{''.join([f"""
|
||||||
|
{{
|
||||||
|
"pub_key": {{
|
||||||
|
"type": "tendermint/PubKeyEd25519",
|
||||||
|
"value": "{v['public_key']}"
|
||||||
|
}},
|
||||||
|
"power": {v['storage']['voting_power']}
|
||||||
|
}}{',' if i + 1 != len(validators) else ''}""" for i, v in enumerate(validators)])}
|
||||||
|
]'''
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_make_sure_we_dont_remove_any_command():
|
def test_make_sure_we_dont_remove_any_command():
|
||||||
# thanks to: http://stackoverflow.com/a/18161115/597097
|
# thanks to: http://stackoverflow.com/a/18161115/597097
|
||||||
from planetmint.commands.planetmint import create_parser
|
from planetmint.commands.planetmint import create_parser
|
||||||
@ -50,22 +147,44 @@ def test_make_sure_we_dont_remove_any_command():
|
|||||||
]
|
]
|
||||||
).command
|
).command
|
||||||
assert parser.parse_args(
|
assert parser.parse_args(
|
||||||
["election", "new", "chain-migration", "--private-key", "TEMP_PATH_TO_PRIVATE_KEY"]
|
[
|
||||||
|
"election",
|
||||||
|
"new",
|
||||||
|
"chain-migration",
|
||||||
|
"--private-key",
|
||||||
|
"TEMP_PATH_TO_PRIVATE_KEY",
|
||||||
|
]
|
||||||
).command
|
).command
|
||||||
assert parser.parse_args(
|
assert parser.parse_args(
|
||||||
["election", "approve", "ELECTION_ID", "--private-key", "TEMP_PATH_TO_PRIVATE_KEY"]
|
[
|
||||||
|
"election",
|
||||||
|
"approve",
|
||||||
|
"ELECTION_ID",
|
||||||
|
"--private-key",
|
||||||
|
"TEMP_PATH_TO_PRIVATE_KEY",
|
||||||
|
]
|
||||||
).command
|
).command
|
||||||
assert parser.parse_args(["election", "show", "ELECTION_ID"]).command
|
assert parser.parse_args(["election", "show", "ELECTION_ID"]).command
|
||||||
assert parser.parse_args(["tendermint-version"]).command
|
assert parser.parse_args(["tendermint-version"]).command
|
||||||
|
|
||||||
|
|
||||||
@patch("planetmint.commands.utils.start")
|
@pytest.mark.bdb
|
||||||
def test_main_entrypoint(mock_start):
|
def test_election_approve_called_with_bad_key(
|
||||||
from planetmint.commands.planetmint import main
|
monkeypatch, caplog, b, bad_validator_path, new_validator, node_key, test_abci_rpc
|
||||||
|
):
|
||||||
|
from argparse import Namespace
|
||||||
|
|
||||||
main()
|
b, election_id = call_election(monkeypatch, b, new_validator, node_key, test_abci_rpc)
|
||||||
|
|
||||||
assert mock_start.called
|
# call run_upsert_validator_approve with args that point to the election, but a bad signing key
|
||||||
|
args = Namespace(action="approve", election_id=election_id, sk=bad_validator_path, config={})
|
||||||
|
|
||||||
|
with caplog.at_level(logging.ERROR):
|
||||||
|
assert not run_election_approve(args, b, test_abci_rpc)
|
||||||
|
assert (
|
||||||
|
caplog.records[0].msg == "The key you provided does not match any of "
|
||||||
|
"the eligible voters in this election."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@patch("planetmint.config_utils.setup_logging")
|
@patch("planetmint.config_utils.setup_logging")
|
||||||
@ -168,7 +287,10 @@ def test_drop_db_does_not_drop_when_interactive_no(mock_db_drop, monkeypatch):
|
|||||||
# switch with pytest. It will just hang. Seems related to the monkeypatching of
|
# switch with pytest. It will just hang. Seems related to the monkeypatching of
|
||||||
# input_on_stderr.
|
# input_on_stderr.
|
||||||
def test_run_configure_when_config_does_not_exist(
|
def test_run_configure_when_config_does_not_exist(
|
||||||
monkeypatch, mock_write_config, mock_generate_key_pair, mock_planetmint_backup_config
|
monkeypatch,
|
||||||
|
mock_write_config,
|
||||||
|
mock_generate_key_pair,
|
||||||
|
mock_planetmint_backup_config,
|
||||||
):
|
):
|
||||||
from planetmint.commands.planetmint import run_configure
|
from planetmint.commands.planetmint import run_configure
|
||||||
|
|
||||||
@ -180,7 +302,10 @@ def test_run_configure_when_config_does_not_exist(
|
|||||||
|
|
||||||
|
|
||||||
def test_run_configure_when_config_does_exist(
|
def test_run_configure_when_config_does_exist(
|
||||||
monkeypatch, mock_write_config, mock_generate_key_pair, mock_planetmint_backup_config
|
monkeypatch,
|
||||||
|
mock_write_config,
|
||||||
|
mock_generate_key_pair,
|
||||||
|
mock_planetmint_backup_config,
|
||||||
):
|
):
|
||||||
value = {}
|
value = {}
|
||||||
|
|
||||||
@ -329,13 +454,18 @@ def test_election_new_upsert_validator_with_tendermint(b, priv_validator_path, u
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.bdb
|
@pytest.mark.bdb
|
||||||
def test_election_new_upsert_validator_without_tendermint(caplog, b, priv_validator_path, user_sk, test_abci_rpc):
|
def test_election_new_upsert_validator_without_tendermint(
|
||||||
def mock_write(modelist, endpoint, mode_commit, transaction, mode):
|
monkeypatch, caplog, b, priv_validator_path, user_sk, test_abci_rpc
|
||||||
|
):
|
||||||
|
def mock_write(self, modelist, endpoint, mode_commit, transaction, mode):
|
||||||
b.models.store_bulk_transactions([transaction])
|
b.models.store_bulk_transactions([transaction])
|
||||||
return (202, "")
|
return (202, "")
|
||||||
|
|
||||||
b.models.get_validators = mock_get_validators
|
with monkeypatch.context() as m:
|
||||||
test_abci_rpc.write_transaction = mock_write
|
from planetmint.model.dataaccessor import DataAccessor
|
||||||
|
|
||||||
|
m.setattr(DataAccessor, "get_validators", mock_get_validators)
|
||||||
|
m.setattr("planetmint.abci.rpc.ABCI_RPC.write_transaction", mock_write)
|
||||||
|
|
||||||
args = Namespace(
|
args = Namespace(
|
||||||
action="new",
|
action="new",
|
||||||
@ -351,6 +481,7 @@ def test_election_new_upsert_validator_without_tendermint(caplog, b, priv_valida
|
|||||||
election_id = run_election_new_upsert_validator(args, b, test_abci_rpc)
|
election_id = run_election_new_upsert_validator(args, b, test_abci_rpc)
|
||||||
assert caplog.records[0].msg == "[SUCCESS] Submitted proposal with id: " + election_id
|
assert caplog.records[0].msg == "[SUCCESS] Submitted proposal with id: " + election_id
|
||||||
assert b.models.get_transaction(election_id)
|
assert b.models.get_transaction(election_id)
|
||||||
|
m.undo()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.abci
|
@pytest.mark.abci
|
||||||
@ -363,13 +494,18 @@ def test_election_new_chain_migration_with_tendermint(b, priv_validator_path, us
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.bdb
|
@pytest.mark.bdb
|
||||||
def test_election_new_chain_migration_without_tendermint(caplog, b, priv_validator_path, user_sk, test_abci_rpc):
|
def test_election_new_chain_migration_without_tendermint(
|
||||||
def mock_write(modelist, endpoint, mode_commit, transaction, mode):
|
monkeypatch, caplog, b, priv_validator_path, user_sk, test_abci_rpc
|
||||||
|
):
|
||||||
|
def mock_write(self, modelist, endpoint, mode_commit, transaction, mode):
|
||||||
b.models.store_bulk_transactions([transaction])
|
b.models.store_bulk_transactions([transaction])
|
||||||
return (202, "")
|
return (202, "")
|
||||||
|
|
||||||
b.models.get_validators = mock_get_validators
|
with monkeypatch.context() as m:
|
||||||
test_abci_rpc.write_transaction = mock_write
|
from planetmint.model.dataaccessor import DataAccessor
|
||||||
|
|
||||||
|
m.setattr(DataAccessor, "get_validators", mock_get_validators)
|
||||||
|
m.setattr("planetmint.abci.rpc.ABCI_RPC.write_transaction", mock_write)
|
||||||
|
|
||||||
args = Namespace(action="new", election_type="migration", sk=priv_validator_path, config={})
|
args = Namespace(action="new", election_type="migration", sk=priv_validator_path, config={})
|
||||||
|
|
||||||
@ -397,15 +533,21 @@ def test_election_new_upsert_validator_invalid_election(caplog, b, priv_validato
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.bdb
|
@pytest.mark.bdb
|
||||||
def test_election_new_upsert_validator_invalid_power(caplog, b, priv_validator_path, user_sk, test_abci_rpc):
|
def test_election_new_upsert_validator_invalid_power(
|
||||||
|
monkeypatch, caplog, b, priv_validator_path, user_sk, test_abci_rpc
|
||||||
|
):
|
||||||
from transactions.common.exceptions import InvalidPowerChange
|
from transactions.common.exceptions import InvalidPowerChange
|
||||||
|
|
||||||
def mock_write(modelist, endpoint, mode_commit, transaction, mode):
|
def mock_write(self, modelist, endpoint, mode_commit, transaction, mode):
|
||||||
b.models.store_bulk_transactions([transaction])
|
b.models.store_bulk_transactions([transaction])
|
||||||
return (400, "")
|
return (400, "")
|
||||||
|
|
||||||
test_abci_rpc.write_transaction = mock_write
|
with monkeypatch.context() as m:
|
||||||
b.models.get_validators = mock_get_validators
|
from planetmint.model.dataaccessor import DataAccessor
|
||||||
|
|
||||||
|
m.setattr(DataAccessor, "get_validators", mock_get_validators)
|
||||||
|
m.setattr("planetmint.abci.rpc.ABCI_RPC.write_transaction", mock_write)
|
||||||
|
|
||||||
args = Namespace(
|
args = Namespace(
|
||||||
action="new",
|
action="new",
|
||||||
election_type="upsert-validator",
|
election_type="upsert-validator",
|
||||||
@ -444,11 +586,23 @@ def test_election_approve_with_tendermint(b, priv_validator_path, user_sk, valid
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.bdb
|
@pytest.mark.bdb
|
||||||
def test_election_approve_without_tendermint(caplog, b, priv_validator_path, new_validator, node_key, test_abci_rpc):
|
def test_election_approve_without_tendermint(
|
||||||
|
monkeypatch, caplog, b, priv_validator_path, new_validator, node_key, test_abci_rpc
|
||||||
|
):
|
||||||
|
def mock_write(self, modelist, endpoint, mode_commit, transaction, mode):
|
||||||
|
b.models.store_bulk_transactions([transaction])
|
||||||
|
return (202, "")
|
||||||
|
|
||||||
from planetmint.commands.planetmint import run_election_approve
|
from planetmint.commands.planetmint import run_election_approve
|
||||||
from argparse import Namespace
|
from argparse import Namespace
|
||||||
|
|
||||||
b, election_id = call_election(b, new_validator, node_key, test_abci_rpc)
|
with monkeypatch.context() as m:
|
||||||
|
from planetmint.model.dataaccessor import DataAccessor
|
||||||
|
|
||||||
|
m.setattr(DataAccessor, "get_validators", mock_get_validators)
|
||||||
|
m.setattr("planetmint.abci.rpc.ABCI_RPC.write_transaction", mock_write)
|
||||||
|
|
||||||
|
b, election_id = call_election_internal(b, new_validator, node_key)
|
||||||
|
|
||||||
# call run_election_approve with args that point to the election
|
# call run_election_approve with args that point to the election
|
||||||
args = Namespace(action="approve", election_id=election_id, sk=priv_validator_path, config={})
|
args = Namespace(action="approve", election_id=election_id, sk=priv_validator_path, config={})
|
||||||
@ -458,13 +612,17 @@ def test_election_approve_without_tendermint(caplog, b, priv_validator_path, new
|
|||||||
approval_id = run_election_approve(args, b, test_abci_rpc)
|
approval_id = run_election_approve(args, b, test_abci_rpc)
|
||||||
assert caplog.records[0].msg == "[SUCCESS] Your vote has been submitted"
|
assert caplog.records[0].msg == "[SUCCESS] Your vote has been submitted"
|
||||||
assert b.models.get_transaction(approval_id)
|
assert b.models.get_transaction(approval_id)
|
||||||
|
m.undo()
|
||||||
|
|
||||||
|
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.bdb
|
@pytest.mark.bdb
|
||||||
def test_election_approve_failure(caplog, b, priv_validator_path, new_validator, node_key, test_abci_rpc):
|
def test_election_approve_failure(monkeypatch, caplog, b, priv_validator_path, new_validator, node_key, test_abci_rpc):
|
||||||
from argparse import Namespace
|
from argparse import Namespace
|
||||||
|
|
||||||
b, election_id = call_election(b, new_validator, node_key, test_abci_rpc)
|
b, election_id = call_election(monkeypatch, b, new_validator, node_key, test_abci_rpc)
|
||||||
|
|
||||||
def mock_write(modelist, endpoint, mode_commit, transaction, mode):
|
def mock_write(modelist, endpoint, mode_commit, transaction, mode):
|
||||||
b.models.store_bulk_transactions([transaction])
|
b.models.store_bulk_transactions([transaction])
|
||||||
@ -480,91 +638,6 @@ def test_election_approve_failure(caplog, b, priv_validator_path, new_validator,
|
|||||||
assert caplog.records[0].msg == "Failed to commit vote"
|
assert caplog.records[0].msg == "Failed to commit vote"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.bdb
|
|
||||||
def test_election_approve_called_with_bad_key(caplog, b, bad_validator_path, new_validator, node_key, test_abci_rpc):
|
|
||||||
from argparse import Namespace
|
|
||||||
|
|
||||||
b, election_id = call_election(b, new_validator, node_key, test_abci_rpc)
|
|
||||||
|
|
||||||
# call run_upsert_validator_approve with args that point to the election, but a bad signing key
|
|
||||||
args = Namespace(action="approve", election_id=election_id, sk=bad_validator_path, config={})
|
|
||||||
|
|
||||||
with caplog.at_level(logging.ERROR):
|
|
||||||
assert not run_election_approve(args, b, test_abci_rpc)
|
|
||||||
assert (
|
|
||||||
caplog.records[0].msg == "The key you provided does not match any of "
|
|
||||||
"the eligible voters in this election."
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.bdb
|
|
||||||
def test_chain_migration_election_show_shows_inconclusive(b):
|
|
||||||
validators = generate_validators([1] * 4)
|
|
||||||
b.models.store_validator_set(1, [v["storage"] for v in validators])
|
|
||||||
|
|
||||||
public_key = validators[0]["public_key"]
|
|
||||||
private_key = validators[0]["private_key"]
|
|
||||||
voter_keys = [v["private_key"] for v in validators]
|
|
||||||
|
|
||||||
election, votes = generate_election(b, ChainMigrationElection, public_key, private_key, [{"data": {}}], voter_keys)
|
|
||||||
|
|
||||||
assert not run_election_show(Namespace(election_id=election.id), b)
|
|
||||||
|
|
||||||
b.process_block(1, [election])
|
|
||||||
b.models.store_bulk_transactions([election])
|
|
||||||
|
|
||||||
assert run_election_show(Namespace(election_id=election.id), b) == "status=ongoing"
|
|
||||||
|
|
||||||
b.models.store_block(Block(height=1, transactions=[], app_hash="")._asdict())
|
|
||||||
b.models.store_validator_set(2, [v["storage"] for v in validators])
|
|
||||||
|
|
||||||
assert run_election_show(Namespace(election_id=election.id), b) == "status=ongoing"
|
|
||||||
|
|
||||||
b.models.store_block(Block(height=2, transactions=[], app_hash="")._asdict())
|
|
||||||
# TODO insert yet another block here when upgrading to Tendermint 0.22.4.
|
|
||||||
|
|
||||||
assert run_election_show(Namespace(election_id=election.id), b) == "status=inconclusive"
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.bdb
|
|
||||||
def test_chain_migration_election_show_shows_concluded(b):
|
|
||||||
validators = generate_validators([1] * 4)
|
|
||||||
b.models.store_validator_set(1, [v["storage"] for v in validators])
|
|
||||||
|
|
||||||
public_key = validators[0]["public_key"]
|
|
||||||
private_key = validators[0]["private_key"]
|
|
||||||
voter_keys = [v["private_key"] for v in validators]
|
|
||||||
|
|
||||||
election, votes = generate_election(b, ChainMigrationElection, public_key, private_key, [{"data": {}}], voter_keys)
|
|
||||||
|
|
||||||
assert not run_election_show(Namespace(election_id=election.id), b)
|
|
||||||
|
|
||||||
b.models.store_bulk_transactions([election])
|
|
||||||
b.process_block(1, [election])
|
|
||||||
|
|
||||||
assert run_election_show(Namespace(election_id=election.id), b) == "status=ongoing"
|
|
||||||
|
|
||||||
b.models.store_abci_chain(1, "chain-X")
|
|
||||||
b.models.store_block(Block(height=1, transactions=[v.id for v in votes], app_hash="last_app_hash")._asdict())
|
|
||||||
b.process_block(2, votes)
|
|
||||||
|
|
||||||
assert (
|
|
||||||
run_election_show(Namespace(election_id=election.id), b)
|
|
||||||
== f'''status=concluded
|
|
||||||
chain_id=chain-X-migrated-at-height-1
|
|
||||||
app_hash=last_app_hash
|
|
||||||
validators=[{''.join([f"""
|
|
||||||
{{
|
|
||||||
"pub_key": {{
|
|
||||||
"type": "tendermint/PubKeyEd25519",
|
|
||||||
"value": "{v['public_key']}"
|
|
||||||
}},
|
|
||||||
"power": {v['storage']['voting_power']}
|
|
||||||
}}{',' if i + 1 != len(validators) else ''}""" for i, v in enumerate(validators)])}
|
|
||||||
]'''
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_bigchain_tendermint_version(capsys):
|
def test_bigchain_tendermint_version(capsys):
|
||||||
from planetmint.commands.planetmint import run_tendermint_version
|
from planetmint.commands.planetmint import run_tendermint_version
|
||||||
|
|
||||||
@ -578,24 +651,7 @@ def test_bigchain_tendermint_version(capsys):
|
|||||||
assert sorted(output_config["tendermint"]) == sorted(__tm_supported_versions__)
|
assert sorted(output_config["tendermint"]) == sorted(__tm_supported_versions__)
|
||||||
|
|
||||||
|
|
||||||
def mock_get_validators(height):
|
def call_election_internal(b, new_validator, node_key):
|
||||||
return [
|
|
||||||
{
|
|
||||||
"public_key": {"value": "zL/DasvKulXZzhSNFwx4cLRXKkSM9GPK7Y0nZ4FEylM=", "type": "ed25519-base64"},
|
|
||||||
"voting_power": 10,
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def call_election(b, new_validator, node_key, abci_rpc):
|
|
||||||
def mock_write(modelist, endpoint, mode_commit, transaction, mode):
|
|
||||||
b.models.store_bulk_transactions([transaction])
|
|
||||||
return (202, "")
|
|
||||||
|
|
||||||
# patch the validator set. We now have one validator with power 10
|
|
||||||
b.models.get_validators = mock_get_validators
|
|
||||||
abci_rpc.write_transaction = mock_write
|
|
||||||
|
|
||||||
# our voters is a list of length 1, populated from our mocked validator
|
# our voters is a list of length 1, populated from our mocked validator
|
||||||
voters = b.get_recipients_list()
|
voters = b.get_recipients_list()
|
||||||
# and our voter is the public key from the voter list
|
# and our voter is the public key from the voter list
|
||||||
@ -607,3 +663,18 @@ def call_election(b, new_validator, node_key, abci_rpc):
|
|||||||
b.models.store_bulk_transactions([valid_election])
|
b.models.store_bulk_transactions([valid_election])
|
||||||
|
|
||||||
return b, election_id
|
return b, election_id
|
||||||
|
|
||||||
|
|
||||||
|
def call_election(monkeypatch, b, new_validator, node_key, abci_rpc):
|
||||||
|
def mock_write(self, modelist, endpoint, mode_commit, transaction, mode):
|
||||||
|
b.models.store_bulk_transactions([transaction])
|
||||||
|
return (202, "")
|
||||||
|
|
||||||
|
with monkeypatch.context() as m:
|
||||||
|
from planetmint.model.dataaccessor import DataAccessor
|
||||||
|
|
||||||
|
m.setattr(DataAccessor, "get_validators", mock_get_validators)
|
||||||
|
m.setattr("planetmint.abci.rpc.ABCI_RPC.write_transaction", mock_write)
|
||||||
|
b, election_id = call_election_internal(b, new_validator, node_key)
|
||||||
|
m.undo()
|
||||||
|
return b, election_id
|
||||||
|
@ -27,7 +27,10 @@ from transactions.common import crypto
|
|||||||
from transactions.common.transaction_mode_types import BROADCAST_TX_COMMIT
|
from transactions.common.transaction_mode_types import BROADCAST_TX_COMMIT
|
||||||
from planetmint.abci.utils import key_from_base64
|
from planetmint.abci.utils import key_from_base64
|
||||||
from planetmint.backend import schema, query
|
from planetmint.backend import schema, query
|
||||||
from transactions.common.crypto import key_pair_from_ed25519_key, public_key_from_ed25519_key
|
from transactions.common.crypto import (
|
||||||
|
key_pair_from_ed25519_key,
|
||||||
|
public_key_from_ed25519_key,
|
||||||
|
)
|
||||||
from planetmint.abci.block import Block
|
from planetmint.abci.block import Block
|
||||||
from planetmint.abci.rpc import MODE_LIST
|
from planetmint.abci.rpc import MODE_LIST
|
||||||
from tests.utils import gen_vote
|
from tests.utils import gen_vote
|
||||||
@ -107,7 +110,10 @@ def _configure_planetmint(request):
|
|||||||
# backend = request.config.getoption('--database-backend')
|
# backend = request.config.getoption('--database-backend')
|
||||||
backend = "tarantool_db"
|
backend = "tarantool_db"
|
||||||
|
|
||||||
config = {"database": Config().get_db_map(backend), "tendermint": Config()._private_real_config["tendermint"]}
|
config = {
|
||||||
|
"database": Config().get_db_map(backend),
|
||||||
|
"tendermint": Config()._private_real_config["tendermint"],
|
||||||
|
}
|
||||||
config["database"]["name"] = test_db_name
|
config["database"]["name"] = test_db_name
|
||||||
config = config_utils.env_config(config)
|
config = config_utils.env_config(config)
|
||||||
config_utils.set_config(config)
|
config_utils.set_config(config)
|
||||||
@ -133,6 +139,28 @@ def _setup_database(_configure_planetmint): # TODO Here is located setup databa
|
|||||||
print("Finished deleting `{}`".format(dbname))
|
print("Finished deleting `{}`".format(dbname))
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def da_reset(_setup_database):
|
||||||
|
from transactions.common.memoize import to_dict, from_dict
|
||||||
|
from transactions.common.transaction import Transaction
|
||||||
|
from .utils import flush_db
|
||||||
|
from planetmint.model.dataaccessor import DataAccessor
|
||||||
|
|
||||||
|
da = DataAccessor()
|
||||||
|
del da
|
||||||
|
da = DataAccessor()
|
||||||
|
da.close_connection()
|
||||||
|
da.connect()
|
||||||
|
|
||||||
|
yield
|
||||||
|
dbname = Config().get()["database"]["name"]
|
||||||
|
flush_db(da.connection, dbname)
|
||||||
|
|
||||||
|
to_dict.cache_clear()
|
||||||
|
from_dict.cache_clear()
|
||||||
|
Transaction._input_valid.cache_clear()
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def _bdb(_setup_database):
|
def _bdb(_setup_database):
|
||||||
from transactions.common.memoize import to_dict, from_dict
|
from transactions.common.memoize import to_dict, from_dict
|
||||||
@ -273,6 +301,38 @@ def test_abci_rpc():
|
|||||||
def b():
|
def b():
|
||||||
from planetmint.application import Validator
|
from planetmint.application import Validator
|
||||||
|
|
||||||
|
old_validator_instance = Validator()
|
||||||
|
del old_validator_instance.models
|
||||||
|
del old_validator_instance
|
||||||
|
validator = Validator()
|
||||||
|
validator.models.connection.close()
|
||||||
|
validator.models.connection.connect()
|
||||||
|
return validator
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def b_flushed(_setup_database):
|
||||||
|
from planetmint.application import Validator
|
||||||
|
from transactions.common.memoize import to_dict, from_dict
|
||||||
|
from transactions.common.transaction import Transaction
|
||||||
|
from .utils import flush_db
|
||||||
|
from planetmint.config import Config
|
||||||
|
|
||||||
|
old_validator_instance = Validator()
|
||||||
|
del old_validator_instance.models
|
||||||
|
del old_validator_instance
|
||||||
|
|
||||||
|
conn = Connection()
|
||||||
|
conn.close()
|
||||||
|
conn.connect()
|
||||||
|
|
||||||
|
dbname = Config().get()["database"]["name"]
|
||||||
|
flush_db(conn, dbname)
|
||||||
|
|
||||||
|
to_dict.cache_clear()
|
||||||
|
from_dict.cache_clear()
|
||||||
|
Transaction._input_valid.cache_clear()
|
||||||
|
|
||||||
validator = Validator()
|
validator = Validator()
|
||||||
validator.models.connection.close()
|
validator.models.connection.close()
|
||||||
validator.models.connection.connect()
|
validator.models.connection.connect()
|
||||||
@ -286,22 +346,6 @@ def eventqueue_fixture():
|
|||||||
return Queue()
|
return Queue()
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def b_mock(b, network_validators):
|
|
||||||
b.models.get_validators = mock_get_validators(network_validators)
|
|
||||||
return b
|
|
||||||
|
|
||||||
|
|
||||||
def mock_get_validators(network_validators):
|
|
||||||
def validator_set(height):
|
|
||||||
validators = []
|
|
||||||
for public_key, power in network_validators.items():
|
|
||||||
validators.append({"public_key": {"type": "ed25519-base64", "value": public_key}, "voting_power": power})
|
|
||||||
return validators
|
|
||||||
|
|
||||||
return validator_set
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def create_tx(alice, user_pk):
|
def create_tx(alice, user_pk):
|
||||||
from transactions.types.assets.create import Create
|
from transactions.types.assets.create import Create
|
||||||
@ -319,7 +363,10 @@ def signed_create_tx(alice, create_tx):
|
|||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def posted_create_tx(b, signed_create_tx, test_abci_rpc):
|
def posted_create_tx(b, signed_create_tx, test_abci_rpc):
|
||||||
res = test_abci_rpc.post_transaction(
|
res = test_abci_rpc.post_transaction(
|
||||||
MODE_LIST, test_abci_rpc.tendermint_rpc_endpoint, signed_create_tx, BROADCAST_TX_COMMIT
|
MODE_LIST,
|
||||||
|
test_abci_rpc.tendermint_rpc_endpoint,
|
||||||
|
signed_create_tx,
|
||||||
|
BROADCAST_TX_COMMIT,
|
||||||
)
|
)
|
||||||
assert res.status_code == 200
|
assert res.status_code == 200
|
||||||
return signed_create_tx
|
return signed_create_tx
|
||||||
@ -356,7 +403,9 @@ def inputs(user_pk, b, alice):
|
|||||||
for height in range(1, 4):
|
for height in range(1, 4):
|
||||||
transactions = [
|
transactions = [
|
||||||
Create.generate(
|
Create.generate(
|
||||||
[alice.public_key], [([user_pk], 1)], metadata=multihash(marshal({"data": f"{random.random()}"}))
|
[alice.public_key],
|
||||||
|
[([user_pk], 1)],
|
||||||
|
metadata=multihash(marshal({"data": f"{random.random()}"})),
|
||||||
).sign([alice.private_key])
|
).sign([alice.private_key])
|
||||||
for _ in range(10)
|
for _ in range(10)
|
||||||
]
|
]
|
||||||
@ -428,7 +477,13 @@ def _abci_http(request):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def abci_http(_setup_database, _configure_planetmint, abci_server, tendermint_host, tendermint_port):
|
def abci_http(
|
||||||
|
_setup_database,
|
||||||
|
_configure_planetmint,
|
||||||
|
abci_server,
|
||||||
|
tendermint_host,
|
||||||
|
tendermint_port,
|
||||||
|
):
|
||||||
import requests
|
import requests
|
||||||
import time
|
import time
|
||||||
|
|
||||||
@ -632,19 +687,19 @@ def new_validator():
|
|||||||
node_id = "fake_node_id"
|
node_id = "fake_node_id"
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{"data": {"public_key": {"value": public_key, "type": "ed25519-base16"}, "power": power, "node_id": node_id}}
|
{
|
||||||
|
"data": {
|
||||||
|
"public_key": {"value": public_key, "type": "ed25519-base16"},
|
||||||
|
"power": power,
|
||||||
|
"node_id": node_id,
|
||||||
|
}
|
||||||
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def valid_upsert_validator_election(b_mock, node_key, new_validator):
|
def valid_upsert_validator_election(b, node_key, new_validator):
|
||||||
voters = b_mock.get_recipients_list()
|
voters = b.get_recipients_list()
|
||||||
return ValidatorElection.generate([node_key.public_key], voters, new_validator, None).sign([node_key.private_key])
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def valid_upsert_validator_election_2(b_mock, node_key, new_validator):
|
|
||||||
voters = b_mock.get_recipients_list()
|
|
||||||
return ValidatorElection.generate([node_key.public_key], voters, new_validator, None).sign([node_key.private_key])
|
return ValidatorElection.generate([node_key.public_key], voters, new_validator, None).sign([node_key.private_key])
|
||||||
|
|
||||||
|
|
||||||
@ -660,40 +715,6 @@ def ongoing_validator_election(b, valid_upsert_validator_election, ed25519_node_
|
|||||||
return valid_upsert_validator_election
|
return valid_upsert_validator_election
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def ongoing_validator_election_2(b, valid_upsert_validator_election_2, ed25519_node_keys):
|
|
||||||
validators = b.models.get_validators(height=1)
|
|
||||||
genesis_validators = {"validators": validators, "height": 0, "election_id": None}
|
|
||||||
query.store_validator_set(b.models.connection, genesis_validators)
|
|
||||||
|
|
||||||
b.models.store_bulk_transactions([valid_upsert_validator_election_2])
|
|
||||||
block_1 = Block(app_hash="hash_2", height=1, transactions=[valid_upsert_validator_election_2.id])
|
|
||||||
b.models.store_block(block_1._asdict())
|
|
||||||
return valid_upsert_validator_election_2
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def validator_election_votes(b_mock, ongoing_validator_election, ed25519_node_keys):
|
|
||||||
voters = b_mock.get_recipients_list()
|
|
||||||
votes = generate_votes(ongoing_validator_election, voters, ed25519_node_keys)
|
|
||||||
return votes
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def validator_election_votes_2(b_mock, ongoing_validator_election_2, ed25519_node_keys):
|
|
||||||
voters = b_mock.get_recipients_list()
|
|
||||||
votes = generate_votes(ongoing_validator_election_2, voters, ed25519_node_keys)
|
|
||||||
return votes
|
|
||||||
|
|
||||||
|
|
||||||
def generate_votes(election, voters, keys):
|
|
||||||
votes = []
|
|
||||||
for voter, _ in enumerate(voters):
|
|
||||||
v = gen_vote(election, voter, keys)
|
|
||||||
votes.append(v)
|
|
||||||
return votes
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def signed_2_0_create_tx():
|
def signed_2_0_create_tx():
|
||||||
return {
|
return {
|
||||||
|
@ -5,10 +5,14 @@ from planetmint.abci.block import Block
|
|||||||
from transactions.types.elections.election import Election
|
from transactions.types.elections.election import Election
|
||||||
from transactions.types.elections.chain_migration_election import ChainMigrationElection
|
from transactions.types.elections.chain_migration_election import ChainMigrationElection
|
||||||
from transactions.types.elections.validator_election import ValidatorElection
|
from transactions.types.elections.validator_election import ValidatorElection
|
||||||
|
from planetmint.model.dataaccessor import DataAccessor
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.bdb
|
@pytest.mark.bdb
|
||||||
def test_process_block_concludes_all_elections(b):
|
def test_process_block_concludes_all_elections(b):
|
||||||
|
del b.models
|
||||||
|
b.models = DataAccessor()
|
||||||
|
b.models.connect()
|
||||||
validators = generate_validators([1] * 4)
|
validators = generate_validators([1] * 4)
|
||||||
b.models.store_validator_set(1, [v["storage"] for v in validators])
|
b.models.store_validator_set(1, [v["storage"] for v in validators])
|
||||||
|
|
||||||
|
@ -1,9 +1,28 @@
|
|||||||
|
import pytest
|
||||||
from transactions.types.elections.chain_migration_election import ChainMigrationElection
|
from transactions.types.elections.chain_migration_election import ChainMigrationElection
|
||||||
|
|
||||||
|
|
||||||
def test_valid_migration_election(b_mock, node_key):
|
@pytest.mark.bdb
|
||||||
voters = b_mock.get_recipients_list()
|
def test_valid_migration_election(monkeypatch, b, node_key, network_validators):
|
||||||
|
def mock_get_validators(self, height):
|
||||||
|
validators = []
|
||||||
|
for public_key, power in network_validators.items():
|
||||||
|
validators.append(
|
||||||
|
{
|
||||||
|
"public_key": {"type": "ed25519-base64", "value": public_key},
|
||||||
|
"voting_power": power,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return validators
|
||||||
|
|
||||||
|
with monkeypatch.context() as m:
|
||||||
|
from planetmint.model.dataaccessor import DataAccessor
|
||||||
|
|
||||||
|
m.setattr(DataAccessor, "get_validators", mock_get_validators)
|
||||||
|
|
||||||
|
voters = b.get_recipients_list()
|
||||||
election = ChainMigrationElection.generate([node_key.public_key], voters, [{"data": {}}], None).sign(
|
election = ChainMigrationElection.generate([node_key.public_key], voters, [{"data": {}}], None).sign(
|
||||||
[node_key.private_key]
|
[node_key.private_key]
|
||||||
)
|
)
|
||||||
assert b_mock.validate_election(election)
|
assert b.validate_election(election)
|
||||||
|
m.undo()
|
||||||
|
@ -46,6 +46,7 @@ def generate_init_chain_request(chain_id, vals=None):
|
|||||||
return types.RequestInitChain(validators=vals, chain_id=chain_id)
|
return types.RequestInitChain(validators=vals, chain_id=chain_id)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.bdb
|
||||||
def test_init_chain_successfully_registers_chain(b):
|
def test_init_chain_successfully_registers_chain(b):
|
||||||
request = generate_init_chain_request("chain-XYZ")
|
request = generate_init_chain_request("chain-XYZ")
|
||||||
res = ApplicationLogic(validator=b).init_chain(request)
|
res = ApplicationLogic(validator=b).init_chain(request)
|
||||||
|
@ -11,15 +11,15 @@ from transactions.types.elections.validator_election import ValidatorElection
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def valid_upsert_validator_election_b(b, node_key, new_validator):
|
def valid_upsert_validator_election(b, node_key, new_validator):
|
||||||
voters = b.get_recipients_list()
|
voters = b.get_recipients_list()
|
||||||
return ValidatorElection.generate([node_key.public_key], voters, new_validator, None).sign([node_key.private_key])
|
return ValidatorElection.generate([node_key.public_key], voters, new_validator, None).sign([node_key.private_key])
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
@patch("transactions.types.elections.election.uuid4", lambda: "mock_uuid4")
|
@patch("transactions.types.elections.election.uuid4", lambda: "mock_uuid4")
|
||||||
def fixed_seed_election(b_mock, node_key, new_validator):
|
def fixed_seed_election(b, node_key, new_validator):
|
||||||
voters = b_mock.get_recipients_list()
|
voters = b.get_recipients_list()
|
||||||
return ValidatorElection.generate([node_key.public_key], voters, new_validator, None).sign([node_key.private_key])
|
return ValidatorElection.generate([node_key.public_key], voters, new_validator, None).sign([node_key.private_key])
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
import pytest
|
import pytest
|
||||||
import codecs
|
import codecs
|
||||||
|
|
||||||
|
from planetmint.model.dataaccessor import DataAccessor
|
||||||
from planetmint.abci.rpc import MODE_LIST, MODE_COMMIT
|
from planetmint.abci.rpc import MODE_LIST, MODE_COMMIT
|
||||||
from planetmint.abci.utils import public_key_to_base64
|
from planetmint.abci.utils import public_key_to_base64
|
||||||
|
|
||||||
@ -22,51 +23,105 @@ from tests.utils import generate_block, gen_vote
|
|||||||
pytestmark = [pytest.mark.execute]
|
pytestmark = [pytest.mark.execute]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.bdb
|
# helper
|
||||||
def test_upsert_validator_valid_election_vote(b_mock, valid_upsert_validator_election, ed25519_node_keys):
|
def get_valid_upsert_election(m, b, mock_get_validators, node_key, new_validator):
|
||||||
b_mock.models.store_bulk_transactions([valid_upsert_validator_election])
|
m.setattr(DataAccessor, "get_validators", mock_get_validators)
|
||||||
|
voters = b.get_recipients_list()
|
||||||
|
valid_upsert_validator_election = ValidatorElection.generate(
|
||||||
|
[node_key.public_key], voters, new_validator, None
|
||||||
|
).sign([node_key.private_key])
|
||||||
|
|
||||||
|
b.models.store_bulk_transactions([valid_upsert_validator_election])
|
||||||
|
return valid_upsert_validator_election
|
||||||
|
|
||||||
|
|
||||||
|
# helper
|
||||||
|
def get_voting_set(valid_upsert_validator_election, ed25519_node_keys):
|
||||||
input0 = valid_upsert_validator_election.to_inputs()[0]
|
input0 = valid_upsert_validator_election.to_inputs()[0]
|
||||||
votes = valid_upsert_validator_election.outputs[0].amount
|
votes = valid_upsert_validator_election.outputs[0].amount
|
||||||
public_key0 = input0.owners_before[0]
|
public_key0 = input0.owners_before[0]
|
||||||
key0 = ed25519_node_keys[public_key0]
|
key0 = ed25519_node_keys[public_key0]
|
||||||
|
return input0, votes, key0
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.bdb
|
||||||
|
def test_upsert_validator_valid_election_vote(
|
||||||
|
monkeypatch, b, network_validators, new_validator, node_key, ed25519_node_keys
|
||||||
|
):
|
||||||
|
def mock_get_validators(self, height):
|
||||||
|
validators = []
|
||||||
|
for public_key, power in network_validators.items():
|
||||||
|
validators.append(
|
||||||
|
{
|
||||||
|
"public_key": {"type": "ed25519-base64", "value": public_key},
|
||||||
|
"voting_power": power,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return validators
|
||||||
|
|
||||||
|
with monkeypatch.context() as m:
|
||||||
|
valid_upsert_validator_election = get_valid_upsert_election(m, b, mock_get_validators, node_key, new_validator)
|
||||||
|
input0, votes, key0 = get_voting_set(valid_upsert_validator_election, ed25519_node_keys)
|
||||||
|
|
||||||
election_pub_key = election_id_to_public_key(valid_upsert_validator_election.id)
|
election_pub_key = election_id_to_public_key(valid_upsert_validator_election.id)
|
||||||
|
|
||||||
vote = Vote.generate(
|
vote = Vote.generate(
|
||||||
[input0], [([election_pub_key], votes)], election_ids=[valid_upsert_validator_election.id]
|
[input0], [([election_pub_key], votes)], election_ids=[valid_upsert_validator_election.id]
|
||||||
).sign([key0.private_key])
|
).sign([key0.private_key])
|
||||||
assert b_mock.validate_transaction(vote)
|
assert b.validate_transaction(vote)
|
||||||
|
m.undo()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.bdb
|
@pytest.mark.bdb
|
||||||
def test_upsert_validator_valid_non_election_vote(b_mock, valid_upsert_validator_election, ed25519_node_keys):
|
def test_upsert_validator_valid_non_election_vote(
|
||||||
b_mock.models.store_bulk_transactions([valid_upsert_validator_election])
|
monkeypatch, b, network_validators, node_key, new_validator, ed25519_node_keys
|
||||||
|
):
|
||||||
|
def mock_get_validators(self, height):
|
||||||
|
validators = []
|
||||||
|
for public_key, power in network_validators.items():
|
||||||
|
validators.append(
|
||||||
|
{
|
||||||
|
"public_key": {"type": "ed25519-base64", "value": public_key},
|
||||||
|
"voting_power": power,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return validators
|
||||||
|
|
||||||
input0 = valid_upsert_validator_election.to_inputs()[0]
|
with monkeypatch.context() as m:
|
||||||
votes = valid_upsert_validator_election.outputs[0].amount
|
valid_upsert_validator_election = get_valid_upsert_election(m, b, mock_get_validators, node_key, new_validator)
|
||||||
public_key0 = input0.owners_before[0]
|
input0, votes, key0 = get_voting_set(valid_upsert_validator_election, ed25519_node_keys)
|
||||||
key0 = ed25519_node_keys[public_key0]
|
|
||||||
|
|
||||||
election_pub_key = election_id_to_public_key(valid_upsert_validator_election.id)
|
election_pub_key = election_id_to_public_key(valid_upsert_validator_election.id)
|
||||||
|
|
||||||
# Ensure that threshold conditions are now allowed
|
# Ensure that threshold conditions are now allowed
|
||||||
with pytest.raises(ValidationError):
|
with pytest.raises(ValidationError):
|
||||||
Vote.generate(
|
Vote.generate(
|
||||||
[input0], [([election_pub_key, key0.public_key], votes)], election_ids=[valid_upsert_validator_election.id]
|
[input0],
|
||||||
|
[([election_pub_key, key0.public_key], votes)],
|
||||||
|
election_ids=[valid_upsert_validator_election.id],
|
||||||
).sign([key0.private_key])
|
).sign([key0.private_key])
|
||||||
|
m.undo()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.bdb
|
@pytest.mark.bdb
|
||||||
def test_upsert_validator_delegate_election_vote(b_mock, valid_upsert_validator_election, ed25519_node_keys):
|
def test_upsert_validator_delegate_election_vote(
|
||||||
|
monkeypatch, b, network_validators, node_key, new_validator, ed25519_node_keys
|
||||||
|
):
|
||||||
|
def mock_get_validators(self, height):
|
||||||
|
validators = []
|
||||||
|
for public_key, power in network_validators.items():
|
||||||
|
validators.append(
|
||||||
|
{
|
||||||
|
"public_key": {"type": "ed25519-base64", "value": public_key},
|
||||||
|
"voting_power": power,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return validators
|
||||||
|
|
||||||
|
with monkeypatch.context() as m:
|
||||||
|
valid_upsert_validator_election = get_valid_upsert_election(m, b, mock_get_validators, node_key, new_validator)
|
||||||
alice = generate_key_pair()
|
alice = generate_key_pair()
|
||||||
|
input0, votes, key0 = get_voting_set(valid_upsert_validator_election, ed25519_node_keys)
|
||||||
b_mock.models.store_bulk_transactions([valid_upsert_validator_election])
|
|
||||||
|
|
||||||
input0 = valid_upsert_validator_election.to_inputs()[0]
|
|
||||||
votes = valid_upsert_validator_election.outputs[0].amount
|
|
||||||
public_key0 = input0.owners_before[0]
|
|
||||||
key0 = ed25519_node_keys[public_key0]
|
|
||||||
|
|
||||||
delegate_vote = Vote.generate(
|
delegate_vote = Vote.generate(
|
||||||
[input0],
|
[input0],
|
||||||
@ -74,32 +129,43 @@ def test_upsert_validator_delegate_election_vote(b_mock, valid_upsert_validator_
|
|||||||
election_ids=[valid_upsert_validator_election.id],
|
election_ids=[valid_upsert_validator_election.id],
|
||||||
).sign([key0.private_key])
|
).sign([key0.private_key])
|
||||||
|
|
||||||
assert b_mock.validate_transaction(delegate_vote)
|
assert b.validate_transaction(delegate_vote)
|
||||||
|
|
||||||
b_mock.models.store_bulk_transactions([delegate_vote])
|
b.models.store_bulk_transactions([delegate_vote])
|
||||||
election_pub_key = election_id_to_public_key(valid_upsert_validator_election.id)
|
election_pub_key = election_id_to_public_key(valid_upsert_validator_election.id)
|
||||||
|
|
||||||
alice_votes = delegate_vote.to_inputs()[0]
|
alice_votes = delegate_vote.to_inputs()[0]
|
||||||
alice_casted_vote = Vote.generate(
|
alice_casted_vote = Vote.generate(
|
||||||
[alice_votes], [([election_pub_key], 3)], election_ids=[valid_upsert_validator_election.id]
|
[alice_votes], [([election_pub_key], 3)], election_ids=[valid_upsert_validator_election.id]
|
||||||
).sign([alice.private_key])
|
).sign([alice.private_key])
|
||||||
assert b_mock.validate_transaction(alice_casted_vote)
|
assert b.validate_transaction(alice_casted_vote)
|
||||||
|
|
||||||
key0_votes = delegate_vote.to_inputs()[1]
|
key0_votes = delegate_vote.to_inputs()[1]
|
||||||
key0_casted_vote = Vote.generate(
|
key0_casted_vote = Vote.generate(
|
||||||
[key0_votes], [([election_pub_key], votes - 3)], election_ids=[valid_upsert_validator_election.id]
|
[key0_votes], [([election_pub_key], votes - 3)], election_ids=[valid_upsert_validator_election.id]
|
||||||
).sign([key0.private_key])
|
).sign([key0.private_key])
|
||||||
assert b_mock.validate_transaction(key0_casted_vote)
|
assert b.validate_transaction(key0_casted_vote)
|
||||||
|
m.undo()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.bdb
|
@pytest.mark.bdb
|
||||||
def test_upsert_validator_invalid_election_vote(b_mock, valid_upsert_validator_election, ed25519_node_keys):
|
def test_upsert_validator_invalid_election_vote(
|
||||||
b_mock.models.store_bulk_transactions([valid_upsert_validator_election])
|
monkeypatch, b, network_validators, node_key, new_validator, ed25519_node_keys
|
||||||
|
):
|
||||||
|
def mock_get_validators(self, height):
|
||||||
|
validators = []
|
||||||
|
for public_key, power in network_validators.items():
|
||||||
|
validators.append(
|
||||||
|
{
|
||||||
|
"public_key": {"type": "ed25519-base64", "value": public_key},
|
||||||
|
"voting_power": power,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return validators
|
||||||
|
|
||||||
input0 = valid_upsert_validator_election.to_inputs()[0]
|
with monkeypatch.context() as m:
|
||||||
votes = valid_upsert_validator_election.outputs[0].amount
|
valid_upsert_validator_election = get_valid_upsert_election(m, b, mock_get_validators, node_key, new_validator)
|
||||||
public_key0 = input0.owners_before[0]
|
input0, votes, key0 = get_voting_set(valid_upsert_validator_election, ed25519_node_keys)
|
||||||
key0 = ed25519_node_keys[public_key0]
|
|
||||||
|
|
||||||
election_pub_key = election_id_to_public_key(valid_upsert_validator_election.id)
|
election_pub_key = election_id_to_public_key(valid_upsert_validator_election.id)
|
||||||
|
|
||||||
@ -108,19 +174,28 @@ def test_upsert_validator_invalid_election_vote(b_mock, valid_upsert_validator_e
|
|||||||
).sign([key0.private_key])
|
).sign([key0.private_key])
|
||||||
|
|
||||||
with pytest.raises(AmountError):
|
with pytest.raises(AmountError):
|
||||||
assert b_mock.validate_transaction(vote)
|
assert b.validate_transaction(vote)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.bdb
|
@pytest.mark.bdb
|
||||||
def test_valid_election_votes_received(b_mock, valid_upsert_validator_election, ed25519_node_keys):
|
def test_valid_election_votes_received(monkeypatch, b, network_validators, node_key, new_validator, ed25519_node_keys):
|
||||||
alice = generate_key_pair()
|
def mock_get_validators(self, height):
|
||||||
b_mock.models.store_bulk_transactions([valid_upsert_validator_election])
|
validators = []
|
||||||
assert b_mock.get_commited_votes(valid_upsert_validator_election) == 0
|
for public_key, power in network_validators.items():
|
||||||
|
validators.append(
|
||||||
|
{
|
||||||
|
"public_key": {"type": "ed25519-base64", "value": public_key},
|
||||||
|
"voting_power": power,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return validators
|
||||||
|
|
||||||
input0 = valid_upsert_validator_election.to_inputs()[0]
|
with monkeypatch.context() as m:
|
||||||
votes = valid_upsert_validator_election.outputs[0].amount
|
valid_upsert_validator_election = get_valid_upsert_election(m, b, mock_get_validators, node_key, new_validator)
|
||||||
public_key0 = input0.owners_before[0]
|
alice = generate_key_pair()
|
||||||
key0 = ed25519_node_keys[public_key0]
|
|
||||||
|
assert b.get_commited_votes(valid_upsert_validator_election) == 0
|
||||||
|
input0, votes, key0 = get_voting_set(valid_upsert_validator_election, ed25519_node_keys)
|
||||||
|
|
||||||
# delegate some votes to alice
|
# delegate some votes to alice
|
||||||
delegate_vote = Vote.generate(
|
delegate_vote = Vote.generate(
|
||||||
@ -128,8 +203,8 @@ def test_valid_election_votes_received(b_mock, valid_upsert_validator_election,
|
|||||||
[([alice.public_key], 4), ([key0.public_key], votes - 4)],
|
[([alice.public_key], 4), ([key0.public_key], votes - 4)],
|
||||||
election_ids=[valid_upsert_validator_election.id],
|
election_ids=[valid_upsert_validator_election.id],
|
||||||
).sign([key0.private_key])
|
).sign([key0.private_key])
|
||||||
b_mock.models.store_bulk_transactions([delegate_vote])
|
b.models.store_bulk_transactions([delegate_vote])
|
||||||
assert b_mock.get_commited_votes(valid_upsert_validator_election) == 0
|
assert b.get_commited_votes(valid_upsert_validator_election) == 0
|
||||||
|
|
||||||
election_public_key = election_id_to_public_key(valid_upsert_validator_election.id)
|
election_public_key = election_id_to_public_key(valid_upsert_validator_election.id)
|
||||||
alice_votes = delegate_vote.to_inputs()[0]
|
alice_votes = delegate_vote.to_inputs()[0]
|
||||||
@ -141,41 +216,61 @@ def test_valid_election_votes_received(b_mock, valid_upsert_validator_election,
|
|||||||
election_ids=[valid_upsert_validator_election.id],
|
election_ids=[valid_upsert_validator_election.id],
|
||||||
).sign([alice.private_key])
|
).sign([alice.private_key])
|
||||||
|
|
||||||
assert b_mock.validate_transaction(alice_casted_vote)
|
assert b.validate_transaction(alice_casted_vote)
|
||||||
b_mock.models.store_bulk_transactions([alice_casted_vote])
|
b.models.store_bulk_transactions([alice_casted_vote])
|
||||||
|
|
||||||
# Check if the delegated vote is count as valid vote
|
# Check if the delegated vote is count as valid vote
|
||||||
assert b_mock.get_commited_votes(valid_upsert_validator_election) == 2
|
assert b.get_commited_votes(valid_upsert_validator_election) == 2
|
||||||
|
|
||||||
key0_casted_vote = Vote.generate(
|
key0_casted_vote = Vote.generate(
|
||||||
[key0_votes], [([election_public_key], votes - 4)], election_ids=[valid_upsert_validator_election.id]
|
[key0_votes], [([election_public_key], votes - 4)], election_ids=[valid_upsert_validator_election.id]
|
||||||
).sign([key0.private_key])
|
).sign([key0.private_key])
|
||||||
|
|
||||||
assert b_mock.validate_transaction(key0_casted_vote)
|
assert b.validate_transaction(key0_casted_vote)
|
||||||
b_mock.models.store_bulk_transactions([key0_casted_vote])
|
b.models.store_bulk_transactions([key0_casted_vote])
|
||||||
assert b_mock.get_commited_votes(valid_upsert_validator_election) == votes - 2
|
assert b.get_commited_votes(valid_upsert_validator_election) == votes - 2
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.bdb
|
@pytest.mark.bdb
|
||||||
def test_valid_election_conclude(b_mock, valid_upsert_validator_election, ed25519_node_keys):
|
def test_valid_election_conclude(monkeypatch, b, network_validators, node_key, new_validator, ed25519_node_keys):
|
||||||
|
def mock_get_validators(self, height):
|
||||||
|
validators = []
|
||||||
|
for public_key, power in network_validators.items():
|
||||||
|
validators.append(
|
||||||
|
{
|
||||||
|
"public_key": {"type": "ed25519-base64", "value": public_key},
|
||||||
|
"voting_power": power,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return validators
|
||||||
|
|
||||||
|
with monkeypatch.context() as m:
|
||||||
|
from planetmint.model.dataaccessor import DataAccessor
|
||||||
|
|
||||||
|
m.setattr(DataAccessor, "get_validators", mock_get_validators)
|
||||||
|
voters = b.get_recipients_list()
|
||||||
|
valid_upsert_validator_election = ValidatorElection.generate(
|
||||||
|
[node_key.public_key], voters, new_validator, None
|
||||||
|
).sign([node_key.private_key])
|
||||||
|
|
||||||
# Node 0: cast vote
|
# Node 0: cast vote
|
||||||
tx_vote0 = gen_vote(valid_upsert_validator_election, 0, ed25519_node_keys)
|
tx_vote0 = gen_vote(valid_upsert_validator_election, 0, ed25519_node_keys)
|
||||||
|
|
||||||
# check if the vote is valid even before the election doesn't exist
|
# check if the vote is valid even before the election doesn't exist
|
||||||
with pytest.raises(ValidationError):
|
with pytest.raises(ValidationError):
|
||||||
assert b_mock.validate_transaction(tx_vote0)
|
assert b.validate_transaction(tx_vote0)
|
||||||
|
|
||||||
# store election
|
# store election
|
||||||
b_mock.models.store_bulk_transactions([valid_upsert_validator_election])
|
b.models.store_bulk_transactions([valid_upsert_validator_election])
|
||||||
# cannot conclude election as not votes exist
|
# cannot conclude election as not votes exist
|
||||||
assert not b_mock.has_election_concluded(valid_upsert_validator_election)
|
assert not b.has_election_concluded(valid_upsert_validator_election)
|
||||||
|
|
||||||
# validate vote
|
# validate vote
|
||||||
assert b_mock.validate_transaction(tx_vote0)
|
assert b.validate_transaction(tx_vote0)
|
||||||
assert not b_mock.has_election_concluded(valid_upsert_validator_election, [tx_vote0])
|
assert not b.has_election_concluded(valid_upsert_validator_election, [tx_vote0])
|
||||||
|
|
||||||
b_mock.models.store_bulk_transactions([tx_vote0])
|
b.models.store_bulk_transactions([tx_vote0])
|
||||||
assert not b_mock.has_election_concluded(valid_upsert_validator_election)
|
assert not b.has_election_concluded(valid_upsert_validator_election)
|
||||||
|
|
||||||
# Node 1: cast vote
|
# Node 1: cast vote
|
||||||
tx_vote1 = gen_vote(valid_upsert_validator_election, 1, ed25519_node_keys)
|
tx_vote1 = gen_vote(valid_upsert_validator_election, 1, ed25519_node_keys)
|
||||||
@ -186,32 +281,32 @@ def test_valid_election_conclude(b_mock, valid_upsert_validator_election, ed2551
|
|||||||
# Node 3: cast vote
|
# Node 3: cast vote
|
||||||
tx_vote3 = gen_vote(valid_upsert_validator_election, 3, ed25519_node_keys)
|
tx_vote3 = gen_vote(valid_upsert_validator_election, 3, ed25519_node_keys)
|
||||||
|
|
||||||
assert b_mock.validate_transaction(tx_vote1)
|
assert b.validate_transaction(tx_vote1)
|
||||||
assert not b_mock.has_election_concluded(valid_upsert_validator_election, [tx_vote1])
|
assert not b.has_election_concluded(valid_upsert_validator_election, [tx_vote1])
|
||||||
|
|
||||||
# 2/3 is achieved in the same block so the election can be.has_concludedd
|
# 2/3 is achieved in the same block so the election can be.has_concludedd
|
||||||
assert b_mock.has_election_concluded(valid_upsert_validator_election, [tx_vote1, tx_vote2])
|
assert b.has_election_concluded(valid_upsert_validator_election, [tx_vote1, tx_vote2])
|
||||||
|
|
||||||
b_mock.models.store_bulk_transactions([tx_vote1])
|
b.models.store_bulk_transactions([tx_vote1])
|
||||||
assert not b_mock.has_election_concluded(valid_upsert_validator_election)
|
assert not b.has_election_concluded(valid_upsert_validator_election)
|
||||||
|
|
||||||
assert b_mock.validate_transaction(tx_vote2)
|
assert b.validate_transaction(tx_vote2)
|
||||||
assert b_mock.validate_transaction(tx_vote3)
|
assert b.validate_transaction(tx_vote3)
|
||||||
|
|
||||||
# conclusion can be triggered my different votes in the same block
|
# conclusion can be triggered my different votes in the same block
|
||||||
assert b_mock.has_election_concluded(valid_upsert_validator_election, [tx_vote2])
|
assert b.has_election_concluded(valid_upsert_validator_election, [tx_vote2])
|
||||||
assert b_mock.has_election_concluded(valid_upsert_validator_election, [tx_vote2, tx_vote3])
|
assert b.has_election_concluded(valid_upsert_validator_election, [tx_vote2, tx_vote3])
|
||||||
|
|
||||||
b_mock.models.store_bulk_transactions([tx_vote2])
|
b.models.store_bulk_transactions([tx_vote2])
|
||||||
|
|
||||||
# Once the blockchain records >2/3 of the votes the election is assumed to be.has_concludedd
|
# Once the blockchain records >2/3 of the votes the election is assumed to be.has_concludedd
|
||||||
# so any invocation of `.has_concluded` for that election should return False
|
# so any invocation of `.has_concluded` for that election should return False
|
||||||
assert not b_mock.has_election_concluded(valid_upsert_validator_election)
|
assert not b.has_election_concluded(valid_upsert_validator_election)
|
||||||
|
|
||||||
# Vote is still valid but the election cannot be.has_concluded as it it assumed that it has
|
# Vote is still valid but the election cannot be.has_concluded as it it assumed that it has
|
||||||
# been.has_concludedd before
|
# been.has_concludedd before
|
||||||
assert b_mock.validate_transaction(tx_vote3)
|
assert b.validate_transaction(tx_vote3)
|
||||||
assert not b_mock.has_election_concluded(valid_upsert_validator_election, [tx_vote3])
|
assert not b.has_election_concluded(valid_upsert_validator_election, [tx_vote3])
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.abci
|
@pytest.mark.abci
|
||||||
|
@ -21,72 +21,176 @@ from transactions.common.exceptions import (
|
|||||||
pytestmark = pytest.mark.bdb
|
pytestmark = pytest.mark.bdb
|
||||||
|
|
||||||
|
|
||||||
def test_upsert_validator_valid_election(b_mock, new_validator, node_key):
|
def test_upsert_validator_valid_election(monkeypatch, b, network_validators, new_validator, node_key):
|
||||||
voters = b_mock.get_recipients_list()
|
def mock_get_validators(self, height):
|
||||||
|
validators = []
|
||||||
|
for public_key, power in network_validators.items():
|
||||||
|
validators.append(
|
||||||
|
{
|
||||||
|
"public_key": {"type": "ed25519-base64", "value": public_key},
|
||||||
|
"voting_power": power,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return validators
|
||||||
|
|
||||||
|
with monkeypatch.context() as m:
|
||||||
|
from planetmint.model.dataaccessor import DataAccessor
|
||||||
|
|
||||||
|
m.setattr(DataAccessor, "get_validators", mock_get_validators)
|
||||||
|
voters = b.get_recipients_list()
|
||||||
election = ValidatorElection.generate([node_key.public_key], voters, new_validator, None).sign(
|
election = ValidatorElection.generate([node_key.public_key], voters, new_validator, None).sign(
|
||||||
[node_key.private_key]
|
[node_key.private_key]
|
||||||
)
|
)
|
||||||
assert b_mock.validate_election(election)
|
assert b.validate_election(election)
|
||||||
|
m.undo()
|
||||||
|
|
||||||
|
|
||||||
def test_upsert_validator_invalid_election_public_key(b_mock, new_validator, node_key):
|
def test_upsert_validator_invalid_election_public_key(monkeypatch, b, network_validators, new_validator, node_key):
|
||||||
|
def mock_get_validators(self, height):
|
||||||
|
validators = []
|
||||||
|
for public_key, power in network_validators.items():
|
||||||
|
validators.append(
|
||||||
|
{
|
||||||
|
"public_key": {"type": "ed25519-base64", "value": public_key},
|
||||||
|
"voting_power": power,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return validators
|
||||||
|
|
||||||
|
with monkeypatch.context() as m:
|
||||||
|
from planetmint.model.dataaccessor import DataAccessor
|
||||||
|
|
||||||
|
m.setattr(DataAccessor, "get_validators", mock_get_validators)
|
||||||
from transactions.common.exceptions import InvalidPublicKey
|
from transactions.common.exceptions import InvalidPublicKey
|
||||||
|
|
||||||
for iv in ["ed25519-base32", "ed25519-base64"]:
|
for iv in ["ed25519-base32", "ed25519-base64"]:
|
||||||
new_validator[0]["data"]["public_key"]["type"] = iv
|
new_validator[0]["data"]["public_key"]["type"] = iv
|
||||||
voters = b_mock.get_recipients_list()
|
voters = b.get_recipients_list()
|
||||||
|
|
||||||
with pytest.raises(InvalidPublicKey):
|
with pytest.raises(InvalidPublicKey):
|
||||||
ValidatorElection.generate([node_key.public_key], voters, new_validator, None).sign([node_key.private_key])
|
ValidatorElection.generate([node_key.public_key], voters, new_validator, None).sign(
|
||||||
|
[node_key.private_key]
|
||||||
|
)
|
||||||
|
m.undo()
|
||||||
|
|
||||||
|
|
||||||
def test_upsert_validator_invalid_power_election(b_mock, new_validator, node_key):
|
def test_upsert_validator_invalid_power_election(monkeypatch, b, network_validators, new_validator, node_key):
|
||||||
voters = b_mock.get_recipients_list()
|
def mock_get_validators(self, height):
|
||||||
|
validators = []
|
||||||
|
for public_key, power in network_validators.items():
|
||||||
|
validators.append(
|
||||||
|
{
|
||||||
|
"public_key": {"type": "ed25519-base64", "value": public_key},
|
||||||
|
"voting_power": power,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return validators
|
||||||
|
|
||||||
|
with monkeypatch.context() as m:
|
||||||
|
from planetmint.model.dataaccessor import DataAccessor
|
||||||
|
|
||||||
|
m.setattr(DataAccessor, "get_validators", mock_get_validators)
|
||||||
|
voters = b.get_recipients_list()
|
||||||
new_validator[0]["data"]["power"] = 30
|
new_validator[0]["data"]["power"] = 30
|
||||||
|
|
||||||
election = ValidatorElection.generate([node_key.public_key], voters, new_validator, None).sign(
|
election = ValidatorElection.generate([node_key.public_key], voters, new_validator, None).sign(
|
||||||
[node_key.private_key]
|
[node_key.private_key]
|
||||||
)
|
)
|
||||||
with pytest.raises(InvalidPowerChange):
|
with pytest.raises(InvalidPowerChange):
|
||||||
b_mock.validate_election(election)
|
b.validate_election(election)
|
||||||
|
m.undo()
|
||||||
|
|
||||||
|
|
||||||
def test_upsert_validator_invalid_proposed_election(b_mock, new_validator, node_key):
|
def test_upsert_validator_invalid_proposed_election(monkeypatch, b, network_validators, new_validator, node_key):
|
||||||
from transactions.common.crypto import generate_key_pair
|
from transactions.common.crypto import generate_key_pair
|
||||||
|
|
||||||
alice = generate_key_pair()
|
def mock_get_validators(self, height):
|
||||||
voters = b_mock.get_recipients_list()
|
validators = []
|
||||||
election = ValidatorElection.generate([alice.public_key], voters, new_validator, None).sign([alice.private_key])
|
for public_key, power in network_validators.items():
|
||||||
with pytest.raises(InvalidProposer):
|
validators.append(
|
||||||
b_mock.validate_election(election)
|
{
|
||||||
|
"public_key": {"type": "ed25519-base64", "value": public_key},
|
||||||
|
"voting_power": power,
|
||||||
def test_upsert_validator_invalid_inputs_election(b_mock, new_validator, node_key):
|
}
|
||||||
from transactions.common.crypto import generate_key_pair
|
|
||||||
|
|
||||||
alice = generate_key_pair()
|
|
||||||
voters = b_mock.get_recipients_list()
|
|
||||||
election = ValidatorElection.generate([node_key.public_key, alice.public_key], voters, new_validator, None).sign(
|
|
||||||
[node_key.private_key, alice.private_key]
|
|
||||||
)
|
)
|
||||||
|
return validators
|
||||||
|
|
||||||
|
with monkeypatch.context() as m:
|
||||||
|
from planetmint.model.dataaccessor import DataAccessor
|
||||||
|
|
||||||
|
m.setattr(DataAccessor, "get_validators", mock_get_validators)
|
||||||
|
|
||||||
|
alice = generate_key_pair()
|
||||||
|
voters = b.get_recipients_list()
|
||||||
|
election = ValidatorElection.generate([alice.public_key], voters, new_validator, None).sign(
|
||||||
|
[alice.private_key]
|
||||||
|
)
|
||||||
|
with pytest.raises(InvalidProposer):
|
||||||
|
b.validate_election(election)
|
||||||
|
|
||||||
|
|
||||||
|
def test_upsert_validator_invalid_inputs_election(monkeypatch, b, network_validators, new_validator, node_key):
|
||||||
|
from transactions.common.crypto import generate_key_pair
|
||||||
|
|
||||||
|
def mock_get_validators(self, height):
|
||||||
|
validators = []
|
||||||
|
for public_key, power in network_validators.items():
|
||||||
|
validators.append(
|
||||||
|
{
|
||||||
|
"public_key": {"type": "ed25519-base64", "value": public_key},
|
||||||
|
"voting_power": power,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return validators
|
||||||
|
|
||||||
|
with monkeypatch.context() as m:
|
||||||
|
from planetmint.model.dataaccessor import DataAccessor
|
||||||
|
|
||||||
|
m.setattr(DataAccessor, "get_validators", mock_get_validators)
|
||||||
|
alice = generate_key_pair()
|
||||||
|
voters = b.get_recipients_list()
|
||||||
|
election = ValidatorElection.generate(
|
||||||
|
[node_key.public_key, alice.public_key], voters, new_validator, None
|
||||||
|
).sign([node_key.private_key, alice.private_key])
|
||||||
with pytest.raises(MultipleInputsError):
|
with pytest.raises(MultipleInputsError):
|
||||||
b_mock.validate_election(election)
|
b.validate_election(election)
|
||||||
|
m.undo()
|
||||||
|
|
||||||
|
|
||||||
@patch("transactions.types.elections.election.uuid4", lambda: "mock_uuid4")
|
@patch("transactions.types.elections.election.uuid4", lambda: "mock_uuid4")
|
||||||
def test_upsert_validator_invalid_election(b_mock, new_validator, node_key, fixed_seed_election):
|
def test_upsert_validator_invalid_election(monkeypatch, b, network_validators, new_validator, node_key):
|
||||||
voters = b_mock.get_recipients_list()
|
def mock_get_validators(self, height):
|
||||||
|
validators = []
|
||||||
|
for public_key, power in network_validators.items():
|
||||||
|
validators.append(
|
||||||
|
{
|
||||||
|
"public_key": {"type": "ed25519-base64", "value": public_key},
|
||||||
|
"voting_power": power,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return validators
|
||||||
|
|
||||||
|
with monkeypatch.context() as m:
|
||||||
|
from planetmint.model.dataaccessor import DataAccessor
|
||||||
|
|
||||||
|
m.setattr(DataAccessor, "get_validators", mock_get_validators)
|
||||||
|
|
||||||
|
voters = b.get_recipients_list()
|
||||||
duplicate_election = ValidatorElection.generate([node_key.public_key], voters, new_validator, None).sign(
|
duplicate_election = ValidatorElection.generate([node_key.public_key], voters, new_validator, None).sign(
|
||||||
[node_key.private_key]
|
[node_key.private_key]
|
||||||
)
|
)
|
||||||
|
voters = b.get_recipients_list()
|
||||||
|
fixed_seed_election = ValidatorElection.generate([node_key.public_key], voters, new_validator, None).sign(
|
||||||
|
[node_key.private_key]
|
||||||
|
)
|
||||||
|
|
||||||
with pytest.raises(DuplicateTransaction):
|
with pytest.raises(DuplicateTransaction):
|
||||||
b_mock.validate_election(fixed_seed_election, [duplicate_election])
|
b.validate_election(fixed_seed_election, [duplicate_election])
|
||||||
|
|
||||||
b_mock.models.store_bulk_transactions([fixed_seed_election])
|
b.models.store_bulk_transactions([fixed_seed_election])
|
||||||
|
|
||||||
with pytest.raises(DuplicateTransaction):
|
with pytest.raises(DuplicateTransaction):
|
||||||
b_mock.validate_election(duplicate_election)
|
b.validate_election(duplicate_election)
|
||||||
|
|
||||||
# Try creating an election with incomplete voter set
|
# Try creating an election with incomplete voter set
|
||||||
invalid_election = ValidatorElection.generate([node_key.public_key], voters[1:], new_validator, None).sign(
|
invalid_election = ValidatorElection.generate([node_key.public_key], voters[1:], new_validator, None).sign(
|
||||||
@ -94,9 +198,9 @@ def test_upsert_validator_invalid_election(b_mock, new_validator, node_key, fixe
|
|||||||
)
|
)
|
||||||
|
|
||||||
with pytest.raises(UnequalValidatorSet):
|
with pytest.raises(UnequalValidatorSet):
|
||||||
b_mock.validate_election(invalid_election)
|
b.validate_election(invalid_election)
|
||||||
|
|
||||||
recipients = b_mock.get_recipients_list()
|
recipients = b.get_recipients_list()
|
||||||
altered_recipients = []
|
altered_recipients = []
|
||||||
for r in recipients:
|
for r in recipients:
|
||||||
([r_public_key], voting_power) = r
|
([r_public_key], voting_power) = r
|
||||||
@ -108,23 +212,89 @@ def test_upsert_validator_invalid_election(b_mock, new_validator, node_key, fixe
|
|||||||
)
|
)
|
||||||
|
|
||||||
with pytest.raises(UnequalValidatorSet):
|
with pytest.raises(UnequalValidatorSet):
|
||||||
b_mock.validate_election(tx_election)
|
b.validate_election(tx_election)
|
||||||
|
m.undo()
|
||||||
|
|
||||||
|
|
||||||
def test_get_status_ongoing(b, ongoing_validator_election, new_validator):
|
def test_get_status_ongoing(monkeypatch, b, network_validators, node_key, new_validator, ed25519_node_keys):
|
||||||
|
def mock_get_validators(self, height):
|
||||||
|
_validators = []
|
||||||
|
for public_key, power in network_validators.items():
|
||||||
|
_validators.append(
|
||||||
|
{
|
||||||
|
"public_key": {"type": "ed25519-base64", "value": public_key},
|
||||||
|
"voting_power": power,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return _validators
|
||||||
|
|
||||||
|
with monkeypatch.context() as m:
|
||||||
|
from planetmint.model.dataaccessor import DataAccessor
|
||||||
|
from planetmint.backend import schema, query
|
||||||
|
from planetmint.abci.block import Block
|
||||||
|
|
||||||
|
m.setattr(DataAccessor, "get_validators", mock_get_validators)
|
||||||
|
|
||||||
|
voters = b.get_recipients_list()
|
||||||
|
valid_upsert_validator_election = ValidatorElection.generate(
|
||||||
|
[node_key.public_key], voters, new_validator, None
|
||||||
|
).sign([node_key.private_key])
|
||||||
|
|
||||||
|
validators = b.models.get_validators(height=1)
|
||||||
|
genesis_validators = {"validators": validators, "height": 0}
|
||||||
|
query.store_validator_set(b.models.connection, genesis_validators)
|
||||||
|
b.models.store_bulk_transactions([valid_upsert_validator_election])
|
||||||
|
query.store_election(b.models.connection, valid_upsert_validator_election.id, 1, is_concluded=False)
|
||||||
|
block_1 = Block(app_hash="hash_1", height=1, transactions=[valid_upsert_validator_election.id])
|
||||||
|
b.models.store_block(block_1._asdict())
|
||||||
|
|
||||||
status = ValidatorElection.ONGOING
|
status = ValidatorElection.ONGOING
|
||||||
resp = b.get_election_status(ongoing_validator_election)
|
resp = b.get_election_status(valid_upsert_validator_election)
|
||||||
assert resp == status
|
assert resp == status
|
||||||
|
m.undo()
|
||||||
|
|
||||||
|
|
||||||
def test_get_status_concluded(b, concluded_election, new_validator):
|
def test_get_status_concluded(monkeypatch, b, network_validators, node_key, new_validator, ed25519_node_keys):
|
||||||
|
def mock_get_validators(self, height):
|
||||||
|
_validators = []
|
||||||
|
for public_key, power in network_validators.items():
|
||||||
|
_validators.append(
|
||||||
|
{
|
||||||
|
"public_key": {"type": "ed25519-base64", "value": public_key},
|
||||||
|
"voting_power": power,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return _validators
|
||||||
|
|
||||||
|
with monkeypatch.context() as m:
|
||||||
|
from planetmint.model.dataaccessor import DataAccessor
|
||||||
|
from planetmint.backend import schema, query
|
||||||
|
from planetmint.abci.block import Block
|
||||||
|
|
||||||
|
m.setattr(DataAccessor, "get_validators", mock_get_validators)
|
||||||
|
|
||||||
|
voters = b.get_recipients_list()
|
||||||
|
valid_upsert_validator_election = ValidatorElection.generate(
|
||||||
|
[node_key.public_key], voters, new_validator, None
|
||||||
|
).sign([node_key.private_key])
|
||||||
|
|
||||||
|
validators = b.models.get_validators(height=1)
|
||||||
|
genesis_validators = {"validators": validators, "height": 0}
|
||||||
|
query.store_validator_set(b.models.connection, genesis_validators)
|
||||||
|
b.models.store_bulk_transactions([valid_upsert_validator_election])
|
||||||
|
query.store_election(b.models.connection, valid_upsert_validator_election.id, 1, is_concluded=False)
|
||||||
|
block_1 = Block(app_hash="hash_1", height=1, transactions=[valid_upsert_validator_election.id])
|
||||||
|
b.models.store_block(block_1._asdict())
|
||||||
|
query.store_election(b.models.connection, valid_upsert_validator_election.id, 2, is_concluded=True)
|
||||||
|
|
||||||
status = ValidatorElection.CONCLUDED
|
status = ValidatorElection.CONCLUDED
|
||||||
resp = b.get_election_status(concluded_election)
|
resp = b.get_election_status(valid_upsert_validator_election)
|
||||||
assert resp == status
|
assert resp == status
|
||||||
|
m.undo()
|
||||||
|
|
||||||
|
|
||||||
def test_get_status_inconclusive(b, inconclusive_election, new_validator):
|
def test_get_status_inconclusive(monkeypatch, b, network_validators, node_key, new_validator):
|
||||||
def set_block_height_to_3():
|
def set_block_height_to_3(self):
|
||||||
return {"height": 3}
|
return {"height": 3}
|
||||||
|
|
||||||
def custom_mock_get_validators(height):
|
def custom_mock_get_validators(height):
|
||||||
@ -167,20 +337,89 @@ def test_get_status_inconclusive(b, inconclusive_election, new_validator):
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
b.models.get_validators = custom_mock_get_validators
|
def mock_get_validators(self, height):
|
||||||
b.models.get_latest_block = set_block_height_to_3
|
_validators = []
|
||||||
|
for public_key, power in network_validators.items():
|
||||||
|
_validators.append(
|
||||||
|
{
|
||||||
|
"public_key": {"type": "ed25519-base64", "value": public_key},
|
||||||
|
"voting_power": power,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return _validators
|
||||||
|
|
||||||
|
with monkeypatch.context() as m:
|
||||||
|
from planetmint.model.dataaccessor import DataAccessor
|
||||||
|
from planetmint.backend import schema, query
|
||||||
|
from planetmint.abci.block import Block
|
||||||
|
|
||||||
|
m.setattr(DataAccessor, "get_validators", mock_get_validators)
|
||||||
|
|
||||||
|
voters = b.get_recipients_list()
|
||||||
|
valid_upsert_validator_election = ValidatorElection.generate(
|
||||||
|
[node_key.public_key], voters, new_validator, None
|
||||||
|
).sign([node_key.private_key])
|
||||||
|
|
||||||
|
validators = b.models.get_validators(height=1)
|
||||||
|
genesis_validators = {"validators": validators, "height": 0}
|
||||||
|
query.store_validator_set(b.models.connection, genesis_validators)
|
||||||
|
b.models.store_bulk_transactions([valid_upsert_validator_election])
|
||||||
|
query.store_election(b.models.connection, valid_upsert_validator_election.id, 1, is_concluded=False)
|
||||||
|
block_1 = Block(app_hash="hash_1", height=1, transactions=[valid_upsert_validator_election.id])
|
||||||
|
b.models.store_block(block_1._asdict())
|
||||||
|
|
||||||
|
validators = b.models.get_validators(height=1)
|
||||||
|
validators[0]["voting_power"] = 15
|
||||||
|
validator_update = {"validators": validators, "height": 2, "election_id": "some_other_election"}
|
||||||
|
|
||||||
|
query.store_validator_set(b.models.connection, validator_update)
|
||||||
|
m.undo()
|
||||||
|
with monkeypatch.context() as m2:
|
||||||
|
m2.setattr(DataAccessor, "get_validators", custom_mock_get_validators)
|
||||||
|
m2.setattr(DataAccessor, "get_latest_block", set_block_height_to_3)
|
||||||
status = ValidatorElection.INCONCLUSIVE
|
status = ValidatorElection.INCONCLUSIVE
|
||||||
resp = b.get_election_status(inconclusive_election)
|
resp = b.get_election_status(valid_upsert_validator_election)
|
||||||
assert resp == status
|
assert resp == status
|
||||||
|
m2.undo()
|
||||||
|
|
||||||
|
|
||||||
def test_upsert_validator_show(caplog, ongoing_validator_election, b):
|
def test_upsert_validator_show(monkeypatch, caplog, b, node_key, new_validator, network_validators):
|
||||||
from planetmint.commands.planetmint import run_election_show
|
from planetmint.commands.planetmint import run_election_show
|
||||||
|
|
||||||
election_id = ongoing_validator_election.id
|
def mock_get_validators(self, height):
|
||||||
public_key = public_key_to_base64(ongoing_validator_election.assets[0]["data"]["public_key"]["value"])
|
_validators = []
|
||||||
power = ongoing_validator_election.assets[0]["data"]["power"]
|
for public_key, power in network_validators.items():
|
||||||
node_id = ongoing_validator_election.assets[0]["data"]["node_id"]
|
_validators.append(
|
||||||
|
{
|
||||||
|
"public_key": {"type": "ed25519-base64", "value": public_key},
|
||||||
|
"voting_power": power,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return _validators
|
||||||
|
|
||||||
|
with monkeypatch.context() as m:
|
||||||
|
from planetmint.model.dataaccessor import DataAccessor
|
||||||
|
from planetmint.backend import schema, query
|
||||||
|
from planetmint.abci.block import Block
|
||||||
|
|
||||||
|
m.setattr(DataAccessor, "get_validators", mock_get_validators)
|
||||||
|
|
||||||
|
voters = b.get_recipients_list()
|
||||||
|
valid_upsert_validator_election = ValidatorElection.generate(
|
||||||
|
[node_key.public_key], voters, new_validator, None
|
||||||
|
).sign([node_key.private_key])
|
||||||
|
|
||||||
|
validators = b.models.get_validators(height=1)
|
||||||
|
genesis_validators = {"validators": validators, "height": 0}
|
||||||
|
query.store_validator_set(b.models.connection, genesis_validators)
|
||||||
|
b.models.store_bulk_transactions([valid_upsert_validator_election])
|
||||||
|
query.store_election(b.models.connection, valid_upsert_validator_election.id, 1, is_concluded=False)
|
||||||
|
block_1 = Block(app_hash="hash_1", height=1, transactions=[valid_upsert_validator_election.id])
|
||||||
|
b.models.store_block(block_1._asdict())
|
||||||
|
election_id = valid_upsert_validator_election.id
|
||||||
|
public_key = public_key_to_base64(valid_upsert_validator_election.assets[0]["data"]["public_key"]["value"])
|
||||||
|
power = valid_upsert_validator_election.assets[0]["data"]["power"]
|
||||||
|
node_id = valid_upsert_validator_election.assets[0]["data"]["node_id"]
|
||||||
status = ValidatorElection.ONGOING
|
status = ValidatorElection.ONGOING
|
||||||
|
|
||||||
show_args = Namespace(action="show", election_id=election_id)
|
show_args = Namespace(action="show", election_id=election_id)
|
||||||
@ -188,3 +427,4 @@ def test_upsert_validator_show(caplog, ongoing_validator_election, b):
|
|||||||
msg = run_election_show(show_args, b)
|
msg = run_election_show(show_args, b)
|
||||||
|
|
||||||
assert msg == f"public_key={public_key}\npower={power}\nnode_id={node_id}\nstatus={status}"
|
assert msg == f"public_key={public_key}\npower={power}\nnode_id={node_id}\nstatus={status}"
|
||||||
|
m.undo()
|
||||||
|
@ -8,6 +8,16 @@ import pytest
|
|||||||
BLOCKS_ENDPOINT = "/api/v1/blocks/"
|
BLOCKS_ENDPOINT = "/api/v1/blocks/"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.bdb
|
||||||
|
@pytest.mark.usefixtures("inputs")
|
||||||
|
def test_get_latest_block(client):
|
||||||
|
res = client.get(BLOCKS_ENDPOINT + "latest")
|
||||||
|
assert res.status_code == 200
|
||||||
|
assert len(res.json["transaction_ids"]) == 10
|
||||||
|
assert res.json["app_hash"] == "hash3"
|
||||||
|
assert res.json["height"] == 3
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.bdb
|
@pytest.mark.bdb
|
||||||
@pytest.mark.usefixtures("inputs")
|
@pytest.mark.usefixtures("inputs")
|
||||||
def test_get_block_returns_404_if_not_found(client):
|
def test_get_block_returns_404_if_not_found(client):
|
||||||
@ -55,16 +65,6 @@ def test_get_blocks_by_txid_endpoint_returns_400_bad_query_params(client):
|
|||||||
assert res.json == {"message": "Unknown arguments: status"}
|
assert res.json == {"message": "Unknown arguments: status"}
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.bdb
|
|
||||||
@pytest.mark.usefixtures("inputs")
|
|
||||||
def test_get_latest_block(client):
|
|
||||||
res = client.get(BLOCKS_ENDPOINT + "latest")
|
|
||||||
assert res.status_code == 200
|
|
||||||
assert len(res.json["transaction_ids"]) == 10
|
|
||||||
assert res.json["app_hash"] == "hash3"
|
|
||||||
assert res.json["height"] == 3
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.bdb
|
@pytest.mark.bdb
|
||||||
@pytest.mark.usefixtures("inputs")
|
@pytest.mark.usefixtures("inputs")
|
||||||
def test_get_block_by_height(client):
|
def test_get_block_by_height(client):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user