From 24637a8b9e14cc86ecaed714da4e7a3f9c6c4040 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Eckel?= Date: Fri, 21 Apr 2023 09:09:49 +0200 Subject: [PATCH] passing all tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jürgen Eckel --- planetmint/application/validator.py | 2 +- tests/commands/test_commands.py | 328 +++++++++----- tests/conftest.py | 103 ++--- tests/migrations/test_migration_election.py | 30 +- tests/tendermint/test_core.py | 2 +- tests/upsert_validator/conftest.py | 6 +- .../test_upsert_validator_vote.py | 377 ++++++++++------ .../test_validator_election.py | 406 ++++++++++++++---- 8 files changed, 841 insertions(+), 413 deletions(-) diff --git a/planetmint/application/validator.py b/planetmint/application/validator.py index d0b59d7..687d2fe 100644 --- a/planetmint/application/validator.py +++ b/planetmint/application/validator.py @@ -492,7 +492,7 @@ class Validator(): self.migrate_abci_chain() if election.operation == VALIDATOR_ELECTION: 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 = [v for v in updated_validator_set if v["voting_power"] > 0] diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index 7f575cb..e32b9fd 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -25,10 +25,14 @@ from planetmint.backend.connection import Connection from tests.utils import generate_election, generate_validators -def mock_get_validators(height): + +def mock_get_validators(self, height): return [ { - "public_key": {"value": "zL/DasvKulXZzhSNFwx4cLRXKkSM9GPK7Y0nZ4FEylM=", "type": "ed25519-base64"}, + "public_key": { + "value": "zL/DasvKulXZzhSNFwx4cLRXKkSM9GPK7Y0nZ4FEylM=", + "type": "ed25519-base64", + }, "voting_power": 10, } ] @@ -38,18 +42,19 @@ def mock_get_validators(height): 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, test_abci_rpc ): - +def test_chain_migration_election_show_shows_inconclusive(b_flushed, test_abci_rpc ): from tests.utils import flush_db - flush_db(b.models.connection, "dbname") + b = b_flushed + validators = generate_validators([1] * 4) output = b.models.store_validator_set(1, [v["storage"] for v in validators]) @@ -57,7 +62,9 @@ def test_chain_migration_election_show_shows_inconclusive(b, test_abci_rpc ): 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) + election, votes = generate_election( + b, ChainMigrationElection, public_key, private_key, [{"data": {}}], voter_keys + ) assert not run_election_show(Namespace(election_id=election.id), b) @@ -74,11 +81,15 @@ def test_chain_migration_election_show_shows_inconclusive(b, test_abci_rpc ): 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" + assert ( + run_election_show(Namespace(election_id=election.id), b) + == "status=inconclusive" + ) @pytest.mark.bdb -def test_chain_migration_election_show_shows_concluded(b): +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]) @@ -86,7 +97,9 @@ def test_chain_migration_election_show_shows_concluded(b): 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) + election, votes = generate_election( + b, ChainMigrationElection, public_key, private_key, [{"data": {}}], voter_keys + ) assert not run_election_show(Namespace(election_id=election.id), b) @@ -96,7 +109,11 @@ def test_chain_migration_election_show_shows_concluded(b): 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.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 ( @@ -140,25 +157,41 @@ def test_make_sure_we_dont_remove_any_command(): ] ).command 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 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 assert parser.parse_args(["election", "show", "ELECTION_ID"]).command assert parser.parse_args(["tendermint-version"]).command - - @pytest.mark.bdb -def test_election_approve_called_with_bad_key(monkeypatch, caplog, b, bad_validator_path, new_validator, node_key, test_abci_rpc): +def test_election_approve_called_with_bad_key( + monkeypatch, caplog, b, bad_validator_path, new_validator, node_key, test_abci_rpc +): from argparse import Namespace - b, election_id = call_election(monkeypatch, b, new_validator, node_key, test_abci_rpc) + b, election_id = call_election( + monkeypatch, 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={}) + 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) @@ -171,7 +204,9 @@ def test_election_approve_called_with_bad_key(monkeypatch, caplog, b, bad_valida @patch("planetmint.config_utils.setup_logging") @patch("planetmint.commands.planetmint._run_init") @patch("planetmint.config_utils.autoconfigure") -def test_bigchain_run_start(mock_setup_logging, mock_run_init, mock_autoconfigure, mock_processes_start): +def test_bigchain_run_start( + mock_setup_logging, mock_run_init, mock_autoconfigure, mock_processes_start +): from planetmint.commands.planetmint import run_start args = Namespace(config=None, yes=True, skip_initialize_database=False) @@ -209,7 +244,9 @@ def test_bigchain_show_config(capsys): def test__run_init(mocker): - init_db_mock = mocker.patch("planetmint.backend.tarantool.sync_io.connection.TarantoolDBConnection.init_database") + init_db_mock = mocker.patch( + "planetmint.backend.tarantool.sync_io.connection.TarantoolDBConnection.init_database" + ) conn = Connection() conn.init_database() @@ -268,7 +305,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 # input_on_stderr. 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 @@ -280,7 +320,10 @@ def test_run_configure_when_config_does_not_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 = {} @@ -319,7 +362,9 @@ def test_run_configure_with_backend(backend, monkeypatch, mock_write_config): # update the expected config with the correct backend and keypair backend_conf = getattr(planetmint, "_database_" + backend) - expected_config.update({"database": backend_conf, "keypair": value["return"]["keypair"]}) + expected_config.update( + {"database": backend_conf, "keypair": value["return"]["keypair"]} + ) assert value["return"] == expected_config @@ -341,12 +386,16 @@ def test_calling_main(start_mock, monkeypatch): assert argparser_mock.called is True parser.add_subparsers.assert_called_with(title="Commands", dest="command") subparsers.add_parser.assert_any_call("configure", help="Prepare the config file.") - subparsers.add_parser.assert_any_call("show-config", help="Show the current " "configuration") + subparsers.add_parser.assert_any_call( + "show-config", help="Show the current " "configuration" + ) subparsers.add_parser.assert_any_call("init", help="Init the database") subparsers.add_parser.assert_any_call("drop", help="Drop the database") subparsers.add_parser.assert_any_call("start", help="Start Planetmint") - subparsers.add_parser.assert_any_call("tendermint-version", help="Show the Tendermint supported " "versions") + subparsers.add_parser.assert_any_call( + "tendermint-version", help="Show the Tendermint supported " "versions" + ) assert start_mock.called is True @@ -386,11 +435,15 @@ def test_run_recover(b, alice, bob, test_models): b.models.store_bulk_transactions([tx1, tx2]) # create a random block - block8 = Block(app_hash="random_app_hash1", height=8, transactions=["txid_doesnt_matter"])._asdict() + block8 = Block( + app_hash="random_app_hash1", height=8, transactions=["txid_doesnt_matter"] + )._asdict() b.models.store_block(block8) # create the next block - block9 = Block(app_hash="random_app_hash1", height=9, transactions=[tx1.id])._asdict() + block9 = Block( + app_hash="random_app_hash1", height=9, transactions=[tx1.id] + )._asdict() b.models.store_block(block9) # create a pre_commit state which is ahead of the commit state @@ -412,7 +465,9 @@ class MockResponse: @pytest.mark.abci -def test_election_new_upsert_validator_with_tendermint(b, priv_validator_path, user_sk, validators, test_abci_rpc): +def test_election_new_upsert_validator_with_tendermint( + b, priv_validator_path, user_sk, validators, test_abci_rpc +): new_args = Namespace( action="new", election_type="upsert-validator", @@ -429,33 +484,46 @@ def test_election_new_upsert_validator_with_tendermint(b, priv_validator_path, u @pytest.mark.bdb -def test_election_new_upsert_validator_without_tendermint(caplog, b, priv_validator_path, user_sk, test_abci_rpc): - def mock_write(modelist, endpoint, mode_commit, transaction, mode): +def test_election_new_upsert_validator_without_tendermint( + 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]) return (202, "") - b.models.get_validators = mock_get_validators - test_abci_rpc.write_transaction = mock_write + with monkeypatch.context() as m: + from planetmint.model.dataaccessor import DataAccessor - args = Namespace( - action="new", - election_type="upsert-validator", - public_key="CJxdItf4lz2PwEf4SmYNAu/c/VpmX39JEgC5YpH7fxg=", - power=1, - node_id="fb7140f03a4ffad899fabbbf655b97e0321add66", - sk=priv_validator_path, - config={}, - ) + m.setattr(DataAccessor, "get_validators", mock_get_validators) + m.setattr("planetmint.abci.rpc.ABCI_RPC.write_transaction", mock_write) - with caplog.at_level(logging.INFO): - 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 b.models.get_transaction(election_id) + args = Namespace( + action="new", + election_type="upsert-validator", + public_key="CJxdItf4lz2PwEf4SmYNAu/c/VpmX39JEgC5YpH7fxg=", + power=1, + node_id="fb7140f03a4ffad899fabbbf655b97e0321add66", + sk=priv_validator_path, + config={}, + ) + + with caplog.at_level(logging.INFO): + 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 b.models.get_transaction(election_id) + m.undo() @pytest.mark.abci -def test_election_new_chain_migration_with_tendermint(b, priv_validator_path, user_sk, validators, test_abci_rpc): - new_args = Namespace(action="new", election_type="migration", sk=priv_validator_path, config={}) +def test_election_new_chain_migration_with_tendermint( + b, priv_validator_path, user_sk, validators, test_abci_rpc +): + new_args = Namespace( + action="new", election_type="migration", sk=priv_validator_path, config={} + ) election_id = run_election_new_chain_migration(new_args, b, test_abci_rpc) @@ -463,24 +531,36 @@ def test_election_new_chain_migration_with_tendermint(b, priv_validator_path, us @pytest.mark.bdb -def test_election_new_chain_migration_without_tendermint(caplog, b, priv_validator_path, user_sk, test_abci_rpc): - def mock_write(modelist, endpoint, mode_commit, transaction, mode): +def test_election_new_chain_migration_without_tendermint( + 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]) return (202, "") - b.models.get_validators = mock_get_validators - test_abci_rpc.write_transaction = mock_write + with monkeypatch.context() as m: + from planetmint.model.dataaccessor import DataAccessor - args = Namespace(action="new", election_type="migration", sk=priv_validator_path, config={}) + m.setattr(DataAccessor, "get_validators", mock_get_validators) + m.setattr("planetmint.abci.rpc.ABCI_RPC.write_transaction", mock_write) - with caplog.at_level(logging.INFO): - election_id = run_election_new_chain_migration(args, b, test_abci_rpc) - assert caplog.records[0].msg == "[SUCCESS] Submitted proposal with id: " + election_id - assert b.models.get_transaction(election_id) + args = Namespace( + action="new", election_type="migration", sk=priv_validator_path, config={} + ) + + with caplog.at_level(logging.INFO): + election_id = run_election_new_chain_migration(args, b, test_abci_rpc) + assert ( + caplog.records[0].msg + == "[SUCCESS] Submitted proposal with id: " + election_id + ) + assert b.models.get_transaction(election_id) @pytest.mark.bdb -def test_election_new_upsert_validator_invalid_election(caplog, b, priv_validator_path, user_sk, test_abci_rpc): +def test_election_new_upsert_validator_invalid_election( + caplog, b, priv_validator_path, user_sk, test_abci_rpc +): args = Namespace( action="new", election_type="upsert-validator", @@ -497,32 +577,40 @@ def test_election_new_upsert_validator_invalid_election(caplog, b, priv_validato @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 - 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]) return (400, "") - test_abci_rpc.write_transaction = mock_write - b.models.get_validators = mock_get_validators - args = Namespace( - action="new", - election_type="upsert-validator", - public_key="CJxdItf4lz2PwEf4SmYNAu/c/VpmX39JEgC5YpH7fxg=", - power=10, - node_id="fb7140f03a4ffad899fabbbf655b97e0321add66", - sk=priv_validator_path, - config={}, - ) + with monkeypatch.context() as m: + from planetmint.model.dataaccessor import DataAccessor - with caplog.at_level(logging.ERROR): - assert not run_election_new_upsert_validator(args, b, test_abci_rpc) - assert caplog.records[0].msg.__class__ == InvalidPowerChange + 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="upsert-validator", + public_key="CJxdItf4lz2PwEf4SmYNAu/c/VpmX39JEgC5YpH7fxg=", + power=10, + node_id="fb7140f03a4ffad899fabbbf655b97e0321add66", + sk=priv_validator_path, + config={}, + ) + + with caplog.at_level(logging.ERROR): + assert not run_election_new_upsert_validator(args, b, test_abci_rpc) + assert caplog.records[0].msg.__class__ == InvalidPowerChange @pytest.mark.abci -def test_election_approve_with_tendermint(b, priv_validator_path, user_sk, validators, test_abci_rpc): +def test_election_approve_with_tendermint( + b, priv_validator_path, user_sk, validators, test_abci_rpc +): public_key = "CJxdItf4lz2PwEf4SmYNAu/c/VpmX39JEgC5YpH7fxg=" new_args = Namespace( action="new", @@ -537,36 +625,61 @@ def test_election_approve_with_tendermint(b, priv_validator_path, user_sk, valid election_id = run_election_new_upsert_validator(new_args, b, test_abci_rpc) assert election_id - 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={} + ) approve = run_election_approve(args, b, test_abci_rpc) assert b.models.get_transaction(approve) @pytest.mark.bdb -def test_election_approve_without_tendermint(monkeypatch, 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 argparse import Namespace + + with monkeypatch.context() as m: + from planetmint.model.dataaccessor import DataAccessor - b, election_id = call_election(monkeypatch, b, new_validator, node_key, test_abci_rpc) + 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 + args = Namespace( + action="approve", election_id=election_id, sk=priv_validator_path, config={} + ) - # call run_election_approve with args that point to the election - args = Namespace(action="approve", election_id=election_id, sk=priv_validator_path, config={}) - - # assert returned id is in the db - with caplog.at_level(logging.INFO): - approval_id = run_election_approve(args, b, test_abci_rpc) - assert caplog.records[0].msg == "[SUCCESS] Your vote has been submitted" - assert b.models.get_transaction(approval_id) + # assert returned id is in the db + with caplog.at_level(logging.INFO): + approval_id = run_election_approve(args, b, test_abci_rpc) + assert caplog.records[0].msg == "[SUCCESS] Your vote has been submitted" + assert b.models.get_transaction(approval_id) + m.undo() from unittest import mock + + @pytest.mark.bdb -def test_election_approve_failure(monkeypatch, 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 - b, election_id = call_election(monkeypatch, 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): b.models.store_bulk_transactions([transaction]) @@ -575,7 +688,9 @@ def test_election_approve_failure(monkeypatch, caplog, b, priv_validator_path, n test_abci_rpc.write_transaction = mock_write # call run_upsert_validator_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={} + ) with caplog.at_level(logging.ERROR): assert not run_election_approve(args, b, test_abci_rpc) @@ -595,29 +710,32 @@ def test_bigchain_tendermint_version(capsys): assert sorted(output_config["tendermint"]) == sorted(__tm_supported_versions__) +def call_election_internal(b, new_validator, node_key): + # our voters is a list of length 1, populated from our mocked validator + voters = b.get_recipients_list() + # and our voter is the public key from the voter list + voter = node_key.public_key + valid_election = ValidatorElection.generate( + [voter], voters, new_validator, None + ).sign([node_key.private_key]) + + # patch in an election with a vote issued to the user + election_id = valid_election.id + b.models.store_bulk_transactions([valid_election]) + + 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: - m.setattr("planetmint.model.dataaccessor.DataAccessor.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) - - # 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 - voters = b.get_recipients_list() - # and our voter is the public key from the voter list - voter = node_key.public_key - valid_election = ValidatorElection.generate([voter], voters, new_validator, None).sign([node_key.private_key]) - - # patch in an election with a vote issued to the user - election_id = valid_election.id - b.models.store_bulk_transactions([valid_election]) - + b, election_id = call_election_internal( b, new_validator, node_key ) m.undo() return b, election_id diff --git a/tests/conftest.py b/tests/conftest.py index 3410d7b..921e92c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -310,6 +310,36 @@ def b(): 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.models.connection.close() + validator.models.connection.connect() + return validator + @pytest.fixture def eventqueue_fixture(): @@ -318,27 +348,6 @@ def eventqueue_fixture(): 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 def create_tx(alice, user_pk): from transactions.types.assets.create import Create @@ -544,6 +553,7 @@ def utxo_collection(tarantool_client, _setup_database): return tarantool_client.get_space("utxos") +@pytest.fixture def network_validators(node_keys): validator_pub_power = {} voting_power = [8, 10, 7, 9] @@ -692,16 +702,8 @@ def new_validator(): @pytest.fixture -def valid_upsert_validator_election(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]) - - -@pytest.fixture -def valid_upsert_validator_election_2(b_mock, node_key, new_validator): - voters = b_mock.get_recipients_list() +def valid_upsert_validator_election(b, node_key, new_validator): + voters = b.get_recipients_list() return ValidatorElection.generate( [node_key.public_key], voters, new_validator, None ).sign([node_key.private_key]) @@ -722,45 +724,6 @@ def ongoing_validator_election(b, valid_upsert_validator_election, ed25519_node_ b.models.store_block(block_1._asdict()) 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 def signed_2_0_create_tx(): return { diff --git a/tests/migrations/test_migration_election.py b/tests/migrations/test_migration_election.py index efedf7f..da1ecfb 100644 --- a/tests/migrations/test_migration_election.py +++ b/tests/migrations/test_migration_election.py @@ -1,9 +1,25 @@ +import pytest from transactions.types.elections.chain_migration_election import ChainMigrationElection - -def test_valid_migration_election(b_mock, node_key): - voters = b_mock.get_recipients_list() - election = ChainMigrationElection.generate([node_key.public_key], voters, [{"data": {}}], None).sign( - [node_key.private_key] - ) - assert b_mock.validate_election(election) +@pytest.mark.bdb +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( + [node_key.private_key] + ) + assert b.validate_election(election) + m.undo() diff --git a/tests/tendermint/test_core.py b/tests/tendermint/test_core.py index 29771c0..4f77b2e 100644 --- a/tests/tendermint/test_core.py +++ b/tests/tendermint/test_core.py @@ -45,7 +45,7 @@ def generate_init_chain_request(chain_id, vals=None): vals = vals if vals is not None else [generate_validator()] return types.RequestInitChain(validators=vals, chain_id=chain_id) - +@pytest.mark.bdb def test_init_chain_successfully_registers_chain(b): request = generate_init_chain_request("chain-XYZ") res = ApplicationLogic(validator=b).init_chain(request) diff --git a/tests/upsert_validator/conftest.py b/tests/upsert_validator/conftest.py index 3ac8eb8..7787f2f 100644 --- a/tests/upsert_validator/conftest.py +++ b/tests/upsert_validator/conftest.py @@ -11,15 +11,15 @@ from transactions.types.elections.validator_election import ValidatorElection @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() return ValidatorElection.generate([node_key.public_key], voters, new_validator, None).sign([node_key.private_key]) @pytest.fixture @patch("transactions.types.elections.election.uuid4", lambda: "mock_uuid4") -def fixed_seed_election(b_mock, node_key, new_validator): - voters = b_mock.get_recipients_list() +def fixed_seed_election(b, node_key, new_validator): + voters = b.get_recipients_list() return ValidatorElection.generate([node_key.public_key], voters, new_validator, None).sign([node_key.private_key]) diff --git a/tests/upsert_validator/test_upsert_validator_vote.py b/tests/upsert_validator/test_upsert_validator_vote.py index 6046ef9..e855b4e 100644 --- a/tests/upsert_validator/test_upsert_validator_vote.py +++ b/tests/upsert_validator/test_upsert_validator_vote.py @@ -23,195 +23,294 @@ pytestmark = [pytest.mark.execute] @pytest.mark.bdb -def test_upsert_validator_valid_election_vote(b_mock, valid_upsert_validator_election, ed25519_node_keys): - b_mock.models.store_bulk_transactions([valid_upsert_validator_election]) +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: + 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]) - 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] + b.models.store_bulk_transactions([valid_upsert_validator_election]) - election_pub_key = election_id_to_public_key(valid_upsert_validator_election.id) + 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] - vote = Vote.generate( - [input0], [([election_pub_key], votes)], election_ids=[valid_upsert_validator_election.id] - ).sign([key0.private_key]) - assert b_mock.validate_transaction(vote) + election_pub_key = election_id_to_public_key(valid_upsert_validator_election.id) + + vote = Vote.generate( + [input0], [([election_pub_key], votes)], election_ids=[valid_upsert_validator_election.id] + ).sign([key0.private_key]) + assert b.validate_transaction(vote) + m.undo() @pytest.mark.bdb -def test_upsert_validator_valid_non_election_vote(b_mock, valid_upsert_validator_election, ed25519_node_keys): - b_mock.models.store_bulk_transactions([valid_upsert_validator_election]) +def test_upsert_validator_valid_non_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: + 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]) - 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] + b.models.store_bulk_transactions([valid_upsert_validator_election]) - election_pub_key = election_id_to_public_key(valid_upsert_validator_election.id) + 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] - # Ensure that threshold conditions are now allowed - with pytest.raises(ValidationError): - Vote.generate( - [input0], [([election_pub_key, key0.public_key], votes)], election_ids=[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 + with pytest.raises(ValidationError): + Vote.generate( + [input0], [([election_pub_key, key0.public_key], votes)], election_ids=[valid_upsert_validator_election.id] + ).sign([key0.private_key]) + m.undo() + + +@pytest.mark.bdb +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: + from planetmint.model.dataaccessor import DataAccessor + m.setattr(DataAccessor, "get_validators", mock_get_validators) + + alice = generate_key_pair() + 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]) + + 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( + [input0], + [([alice.public_key], 3), ([key0.public_key], votes - 3)], + election_ids=[valid_upsert_validator_election.id], ).sign([key0.private_key]) + assert b.validate_transaction(delegate_vote) -@pytest.mark.bdb -def test_upsert_validator_delegate_election_vote(b_mock, valid_upsert_validator_election, ed25519_node_keys): - alice = generate_key_pair() + b.models.store_bulk_transactions([delegate_vote]) + election_pub_key = election_id_to_public_key(valid_upsert_validator_election.id) - b_mock.models.store_bulk_transactions([valid_upsert_validator_election]) + alice_votes = delegate_vote.to_inputs()[0] + alice_casted_vote = Vote.generate( + [alice_votes], [([election_pub_key], 3)], election_ids=[valid_upsert_validator_election.id] + ).sign([alice.private_key]) + assert b.validate_transaction(alice_casted_vote) - 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( - [input0], - [([alice.public_key], 3), ([key0.public_key], votes - 3)], - election_ids=[valid_upsert_validator_election.id], - ).sign([key0.private_key]) - - assert b_mock.validate_transaction(delegate_vote) - - b_mock.models.store_bulk_transactions([delegate_vote]) - election_pub_key = election_id_to_public_key(valid_upsert_validator_election.id) - - alice_votes = delegate_vote.to_inputs()[0] - alice_casted_vote = Vote.generate( - [alice_votes], [([election_pub_key], 3)], election_ids=[valid_upsert_validator_election.id] - ).sign([alice.private_key]) - assert b_mock.validate_transaction(alice_casted_vote) - - key0_votes = delegate_vote.to_inputs()[1] - key0_casted_vote = Vote.generate( - [key0_votes], [([election_pub_key], votes - 3)], election_ids=[valid_upsert_validator_election.id] - ).sign([key0.private_key]) - assert b_mock.validate_transaction(key0_casted_vote) + key0_votes = delegate_vote.to_inputs()[1] + key0_casted_vote = Vote.generate( + [key0_votes], [([election_pub_key], votes - 3)], election_ids=[valid_upsert_validator_election.id] + ).sign([key0.private_key]) + assert b.validate_transaction(key0_casted_vote) + m.undo() @pytest.mark.bdb -def test_upsert_validator_invalid_election_vote(b_mock, valid_upsert_validator_election, ed25519_node_keys): - b_mock.models.store_bulk_transactions([valid_upsert_validator_election]) +def test_upsert_validator_invalid_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: + 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]) - 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] + b.models.store_bulk_transactions([valid_upsert_validator_election]) - election_pub_key = election_id_to_public_key(valid_upsert_validator_election.id) + 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] - vote = Vote.generate( - [input0], [([election_pub_key], votes + 1)], election_ids=[valid_upsert_validator_election.id] - ).sign([key0.private_key]) + election_pub_key = election_id_to_public_key(valid_upsert_validator_election.id) - with pytest.raises(AmountError): - assert b_mock.validate_transaction(vote) + vote = Vote.generate( + [input0], [([election_pub_key], votes + 1)], election_ids=[valid_upsert_validator_election.id] + ).sign([key0.private_key]) + + with pytest.raises(AmountError): + assert b.validate_transaction(vote) @pytest.mark.bdb -def test_valid_election_votes_received(b_mock, valid_upsert_validator_election, ed25519_node_keys): - alice = generate_key_pair() - b_mock.models.store_bulk_transactions([valid_upsert_validator_election]) - assert b_mock.get_commited_votes(valid_upsert_validator_election) == 0 +def test_valid_election_votes_received(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) + alice = generate_key_pair() + voters = b.get_recipients_list() + valid_upsert_validator_election= ValidatorElection.generate([node_key.public_key], voters, new_validator, None).sign([node_key.private_key]) - 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] + b.models.store_bulk_transactions([valid_upsert_validator_election]) + assert b.get_commited_votes(valid_upsert_validator_election) == 0 - # delegate some votes to alice - delegate_vote = Vote.generate( - [input0], - [([alice.public_key], 4), ([key0.public_key], votes - 4)], - election_ids=[valid_upsert_validator_election.id], - ).sign([key0.private_key]) - b_mock.models.store_bulk_transactions([delegate_vote]) - assert b_mock.get_commited_votes(valid_upsert_validator_election) == 0 + 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] - election_public_key = election_id_to_public_key(valid_upsert_validator_election.id) - alice_votes = delegate_vote.to_inputs()[0] - key0_votes = delegate_vote.to_inputs()[1] + # delegate some votes to alice + delegate_vote = Vote.generate( + [input0], + [([alice.public_key], 4), ([key0.public_key], votes - 4)], + election_ids=[valid_upsert_validator_election.id], + ).sign([key0.private_key]) + b.models.store_bulk_transactions([delegate_vote]) + assert b.get_commited_votes(valid_upsert_validator_election) == 0 - alice_casted_vote = Vote.generate( - [alice_votes], - [([election_public_key], 2), ([alice.public_key], 2)], - election_ids=[valid_upsert_validator_election.id], - ).sign([alice.private_key]) + election_public_key = election_id_to_public_key(valid_upsert_validator_election.id) + alice_votes = delegate_vote.to_inputs()[0] + key0_votes = delegate_vote.to_inputs()[1] - assert b_mock.validate_transaction(alice_casted_vote) - b_mock.models.store_bulk_transactions([alice_casted_vote]) + alice_casted_vote = Vote.generate( + [alice_votes], + [([election_public_key], 2), ([alice.public_key], 2)], + election_ids=[valid_upsert_validator_election.id], + ).sign([alice.private_key]) - # Check if the delegated vote is count as valid vote - assert b_mock.get_commited_votes(valid_upsert_validator_election) == 2 + assert b.validate_transaction(alice_casted_vote) + b.models.store_bulk_transactions([alice_casted_vote]) - key0_casted_vote = Vote.generate( - [key0_votes], [([election_public_key], votes - 4)], election_ids=[valid_upsert_validator_election.id] - ).sign([key0.private_key]) + # Check if the delegated vote is count as valid vote + assert b.get_commited_votes(valid_upsert_validator_election) == 2 - assert b_mock.validate_transaction(key0_casted_vote) - b_mock.models.store_bulk_transactions([key0_casted_vote]) - assert b_mock.get_commited_votes(valid_upsert_validator_election) == votes - 2 + key0_casted_vote = Vote.generate( + [key0_votes], [([election_public_key], votes - 4)], election_ids=[valid_upsert_validator_election.id] + ).sign([key0.private_key]) + + assert b.validate_transaction(key0_casted_vote) + b.models.store_bulk_transactions([key0_casted_vote]) + assert b.get_commited_votes(valid_upsert_validator_election) == votes - 2 @pytest.mark.bdb -def test_valid_election_conclude(b_mock, valid_upsert_validator_election, ed25519_node_keys): - # Node 0: cast vote - tx_vote0 = gen_vote(valid_upsert_validator_election, 0, 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]) - # check if the vote is valid even before the election doesn't exist - with pytest.raises(ValidationError): - assert b_mock.validate_transaction(tx_vote0) + # Node 0: cast vote + tx_vote0 = gen_vote(valid_upsert_validator_election, 0, ed25519_node_keys) - # store election - b_mock.models.store_bulk_transactions([valid_upsert_validator_election]) - # cannot conclude election as not votes exist - assert not b_mock.has_election_concluded(valid_upsert_validator_election) + # check if the vote is valid even before the election doesn't exist + with pytest.raises(ValidationError): + assert b.validate_transaction(tx_vote0) - # validate vote - assert b_mock.validate_transaction(tx_vote0) - assert not b_mock.has_election_concluded(valid_upsert_validator_election, [tx_vote0]) + # store election + b.models.store_bulk_transactions([valid_upsert_validator_election]) + # cannot conclude election as not votes exist + assert not b.has_election_concluded(valid_upsert_validator_election) - b_mock.models.store_bulk_transactions([tx_vote0]) - assert not b_mock.has_election_concluded(valid_upsert_validator_election) + # validate vote + assert b.validate_transaction(tx_vote0) + assert not b.has_election_concluded(valid_upsert_validator_election, [tx_vote0]) - # Node 1: cast vote - tx_vote1 = gen_vote(valid_upsert_validator_election, 1, ed25519_node_keys) + b.models.store_bulk_transactions([tx_vote0]) + assert not b.has_election_concluded(valid_upsert_validator_election) - # Node 2: cast vote - tx_vote2 = gen_vote(valid_upsert_validator_election, 2, ed25519_node_keys) + # Node 1: cast vote + tx_vote1 = gen_vote(valid_upsert_validator_election, 1, ed25519_node_keys) - # Node 3: cast vote - tx_vote3 = gen_vote(valid_upsert_validator_election, 3, ed25519_node_keys) + # Node 2: cast vote + tx_vote2 = gen_vote(valid_upsert_validator_election, 2, ed25519_node_keys) - assert b_mock.validate_transaction(tx_vote1) - assert not b_mock.has_election_concluded(valid_upsert_validator_election, [tx_vote1]) + # Node 3: cast vote + tx_vote3 = gen_vote(valid_upsert_validator_election, 3, ed25519_node_keys) - # 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.validate_transaction(tx_vote1) + assert not b.has_election_concluded(valid_upsert_validator_election, [tx_vote1]) - b_mock.models.store_bulk_transactions([tx_vote1]) - assert not b_mock.has_election_concluded(valid_upsert_validator_election) + # 2/3 is achieved in the same block so the election can be.has_concludedd + assert b.has_election_concluded(valid_upsert_validator_election, [tx_vote1, tx_vote2]) - assert b_mock.validate_transaction(tx_vote2) - assert b_mock.validate_transaction(tx_vote3) + b.models.store_bulk_transactions([tx_vote1]) + assert not b.has_election_concluded(valid_upsert_validator_election) - # 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_mock.has_election_concluded(valid_upsert_validator_election, [tx_vote2, tx_vote3]) + assert b.validate_transaction(tx_vote2) + assert b.validate_transaction(tx_vote3) - b_mock.models.store_bulk_transactions([tx_vote2]) + # conclusion can be triggered my different votes in the same block + assert b.has_election_concluded(valid_upsert_validator_election, [tx_vote2]) + assert b.has_election_concluded(valid_upsert_validator_election, [tx_vote2, tx_vote3]) - # 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 - assert not b_mock.has_election_concluded(valid_upsert_validator_election) + b.models.store_bulk_transactions([tx_vote2]) - # Vote is still valid but the election cannot be.has_concluded as it it assumed that it has - # been.has_concludedd before - assert b_mock.validate_transaction(tx_vote3) - assert not b_mock.has_election_concluded(valid_upsert_validator_election, [tx_vote3]) + # 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 + 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 + # been.has_concludedd before + assert b.validate_transaction(tx_vote3) + assert not b.has_election_concluded(valid_upsert_validator_election, [tx_vote3]) @pytest.mark.abci diff --git a/tests/upsert_validator/test_validator_election.py b/tests/upsert_validator/test_validator_election.py index 57c1bc1..e320d75 100644 --- a/tests/upsert_validator/test_validator_election.py +++ b/tests/upsert_validator/test_validator_election.py @@ -21,110 +21,268 @@ from transactions.common.exceptions import ( pytestmark = pytest.mark.bdb -def test_upsert_validator_valid_election(b_mock, new_validator, node_key): - voters = b_mock.get_recipients_list() - election = ValidatorElection.generate([node_key.public_key], voters, new_validator, None).sign( - [node_key.private_key] - ) - assert b_mock.validate_election(election) +def test_upsert_validator_valid_election(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) + voters = b.get_recipients_list() + election = ValidatorElection.generate([node_key.public_key], voters, new_validator, None).sign( + [node_key.private_key] + ) + assert b.validate_election(election) + m.undo() -def test_upsert_validator_invalid_election_public_key(b_mock, new_validator, node_key): - from transactions.common.exceptions import InvalidPublicKey +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 - for iv in ["ed25519-base32", "ed25519-base64"]: - new_validator[0]["data"]["public_key"]["type"] = iv - voters = b_mock.get_recipients_list() + for iv in ["ed25519-base32", "ed25519-base64"]: + new_validator[0]["data"]["public_key"]["type"] = iv + voters = b.get_recipients_list() - with pytest.raises(InvalidPublicKey): - ValidatorElection.generate([node_key.public_key], voters, new_validator, None).sign([node_key.private_key]) + with pytest.raises(InvalidPublicKey): + 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): - voters = b_mock.get_recipients_list() - new_validator[0]["data"]["power"] = 30 +def test_upsert_validator_invalid_power_election(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) + voters = b.get_recipients_list() + new_validator[0]["data"]["power"] = 30 - election = ValidatorElection.generate([node_key.public_key], voters, new_validator, None).sign( - [node_key.private_key] - ) - with pytest.raises(InvalidPowerChange): - b_mock.validate_election(election) + election = ValidatorElection.generate([node_key.public_key], voters, new_validator, None).sign( + [node_key.private_key] + ) + with pytest.raises(InvalidPowerChange): + 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 + 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_mock.get_recipients_list() - election = ValidatorElection.generate([alice.public_key], voters, new_validator, None).sign([alice.private_key]) - with pytest.raises(InvalidProposer): - b_mock.validate_election(election) + 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(b_mock, new_validator, node_key): +def test_upsert_validator_invalid_inputs_election(monkeypatch, b, network_validators, 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] - ) - with pytest.raises(MultipleInputsError): - b_mock.validate_election(election) + 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): + b.validate_election(election) + m.undo() @patch("transactions.types.elections.election.uuid4", lambda: "mock_uuid4") -def test_upsert_validator_invalid_election(b_mock, new_validator, node_key, fixed_seed_election): - voters = b_mock.get_recipients_list() - duplicate_election = ValidatorElection.generate([node_key.public_key], voters, new_validator, None).sign( - [node_key.private_key] - ) +def test_upsert_validator_invalid_election(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) + + + voters = b.get_recipients_list() + duplicate_election = ValidatorElection.generate([node_key.public_key], voters, new_validator, None).sign( + [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): - b_mock.validate_election(fixed_seed_election, [duplicate_election]) + with pytest.raises(DuplicateTransaction): + 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): - b_mock.validate_election(duplicate_election) + with pytest.raises(DuplicateTransaction): + b.validate_election(duplicate_election) - # Try creating an election with incomplete voter set - invalid_election = ValidatorElection.generate([node_key.public_key], voters[1:], new_validator, None).sign( - [node_key.private_key] - ) + # Try creating an election with incomplete voter set + invalid_election = ValidatorElection.generate([node_key.public_key], voters[1:], new_validator, None).sign( + [node_key.private_key] + ) - with pytest.raises(UnequalValidatorSet): - b_mock.validate_election(invalid_election) + with pytest.raises(UnequalValidatorSet): + b.validate_election(invalid_election) - recipients = b_mock.get_recipients_list() - altered_recipients = [] - for r in recipients: - ([r_public_key], voting_power) = r - altered_recipients.append(([r_public_key], voting_power - 1)) + recipients = b.get_recipients_list() + altered_recipients = [] + for r in recipients: + ([r_public_key], voting_power) = r + altered_recipients.append(([r_public_key], voting_power - 1)) - # Create a transaction which doesn't enfore the network power - tx_election = ValidatorElection.generate([node_key.public_key], altered_recipients, new_validator, None).sign( - [node_key.private_key] - ) + # Create a transaction which doesn't enfore the network power + tx_election = ValidatorElection.generate([node_key.public_key], altered_recipients, new_validator, None).sign( + [node_key.private_key] + ) - with pytest.raises(UnequalValidatorSet): - b_mock.validate_election(tx_election) + with pytest.raises(UnequalValidatorSet): + b.validate_election(tx_election) + m.undo() -def test_get_status_ongoing(b, ongoing_validator_election, new_validator): - status = ValidatorElection.ONGOING - resp = b.get_election_status(ongoing_validator_election) - assert resp == status +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 + resp = b.get_election_status(valid_upsert_validator_election) + assert resp == status + m.undo() -def test_get_status_concluded(b, concluded_election, new_validator): - status = ValidatorElection.CONCLUDED - resp = b.get_election_status(concluded_election) - assert resp == status +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 + resp = b.get_election_status(valid_upsert_validator_election) + assert resp == status + m.undo() -def test_get_status_inconclusive(b, inconclusive_election, new_validator): - def set_block_height_to_3(): +def test_get_status_inconclusive(monkeypatch, b, network_validators, node_key, new_validator): + + + def set_block_height_to_3(self): return {"height": 3} def custom_mock_get_validators(height): @@ -166,25 +324,99 @@ def test_get_status_inconclusive(b, inconclusive_election, new_validator): "voting_power": 8, }, ] + 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) - b.models.get_validators = custom_mock_get_validators - b.models.get_latest_block = set_block_height_to_3 - status = ValidatorElection.INCONCLUSIVE - resp = b.get_election_status(inconclusive_election) - assert resp == status + 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()) -def test_upsert_validator_show(caplog, ongoing_validator_election, b): + + 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 + resp = b.get_election_status(valid_upsert_validator_election) + assert resp == status + m2.undo() + + +def test_upsert_validator_show(monkeypatch, caplog, b, node_key, new_validator, network_validators): from planetmint.commands.planetmint import run_election_show + 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) - election_id = ongoing_validator_election.id - public_key = public_key_to_base64(ongoing_validator_election.assets[0]["data"]["public_key"]["value"]) - power = ongoing_validator_election.assets[0]["data"]["power"] - node_id = ongoing_validator_election.assets[0]["data"]["node_id"] - status = ValidatorElection.ONGOING + voters = b.get_recipients_list() + valid_upsert_validator_election= ValidatorElection.generate( + [node_key.public_key], voters, new_validator, None + ).sign([node_key.private_key]) - show_args = Namespace(action="show", election_id=election_id) + 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 - msg = run_election_show(show_args, b) + show_args = Namespace(action="show", election_id=election_id) - assert msg == f"public_key={public_key}\npower={power}\nnode_id={node_id}\nstatus={status}" + msg = run_election_show(show_args, b) + + assert msg == f"public_key={public_key}\npower={power}\nnode_id={node_id}\nstatus={status}" + m.undo()