<commit_before>import pytest

from plenum.common.constants import LEDGER_STATUS
from plenum.common.messages.fields import LedgerIdField, NonNegativeNumberField, \
    MerkleRootField
from plenum.common.messages.message_base import MessageBase
from plenum.test.helper import sdk_send_random_and_check
from plenum.test.node_catchup.helper import waitNodeDataEquality
from plenum.test.node_catchup.test_config_ledger import start_stopped_node
from plenum.test.pool_transactions.helper import \
    disconnect_node_and_ensure_disconnected
from plenum.test.test_node import checkNodesConnected
from plenum.common.types import f


def test_node_catchup_with_new_ls_form(txnPoolNodeSet,
                                       looper,
                                       sdk_pool_handle,
                                       sdk_wallet_steward,
                                       tconf,
                                       tdir,
                                       allPluginsPath):
    '''
    One node restart and in catchup receive Ledger Status without protocol
    version from the one of nodes in pool.
    '''
    node_to_disconnect = txnPoolNodeSet[-1]
    break_node = txnPoolNodeSet[0]

    sdk_send_random_and_check(looper, txnPoolNodeSet,
                              sdk_pool_handle, sdk_wallet_steward, 5)

    original_get_ledger_status = break_node.getLedgerStatus

    # Path the method getLedgerStatus to
    # get_ledger_status_without_protocol_version for sending ledger status
    # without protocol version.

    def get_ledger_status_without_protocol_version(ledgerId: int):
        original_ledger_status = original_get_ledger_status(ledgerId)
        return CustomLedgerStatus(original_ledger_status.ledgerId,
                                  original_ledger_status.txnSeqNo,
                                  original_ledger_status.viewNo,
                                  original_ledger_status.ppSeqNo,
                                  original_ledger_status.merkleRoot)

    break_node.getLedgerStatus = get_ledger_status_without_protocol_version

    # restart node
    disconnect_node_and_ensure_disconnected(looper,
                                            txnPoolNodeSet,
                                            node_to_disconnect)
    looper.removeProdable(name=node_to_disconnect.name)
    sdk_send_random_and_check(looper, txnPoolNodeSet,
                              sdk_pool_handle, sdk_wallet_steward,
                              2)

    # add node_to_disconnect to pool
    node_to_disconnect = start_stopped_node(node_to_disconnect, looper, tconf,
                                            tdir, allPluginsPath)
    txnPoolNodeSet[-1] = node_to_disconnect
    looper.run(checkNodesConnected(txnPoolNodeSet))
    waitNodeDataEquality(looper, node_to_disconnect, *txnPoolNodeSet)
    sdk_send_random_and_check(looper, txnPoolNodeSet,
                              sdk_pool_handle, sdk_wallet_steward, 5)
    waitNodeDataEquality(looper, node_to_disconnect, *txnPoolNodeSet)


class CustomLedgerStatus(MessageBase):
    """
    LedgerStatus class without protocol version
    """
    typename = LEDGER_STATUS
    schema = (
        (f.LEDGER_ID.nm, LedgerIdField()),
        (f.TXN_SEQ_NO.nm, NonNegativeNumberField()),
        (f.VIEW_NO.nm, NonNegativeNumberField(nullable=True)),
        (f.PP_SEQ_NO.nm, NonNegativeNumberField(nullable=True)),
        (f.MERKLE_ROOT.nm, MerkleRootField())
    )<commit_msg>Add check discarding Ledger Statuses test_node_catchup_with_new_ls_form<commit_after>import pytest

from plenum.common.constants import LEDGER_STATUS
from plenum.common.messages.fields import LedgerIdField, NonNegativeNumberField, \
    MerkleRootField
from plenum.common.messages.message_base import MessageBase
from plenum.test.helper import sdk_send_random_and_check, countDiscarded
from plenum.test.node_catchup.helper import waitNodeDataEquality
from plenum.test.node_catchup.test_config_ledger import start_stopped_node
from plenum.test.pool_transactions.helper import \
    disconnect_node_and_ensure_disconnected
from plenum.test.test_node import checkNodesConnected
from plenum.common.types import f


def test_node_catchup_with_new_ls_form(txnPoolNodeSet,
                                       looper,
                                       sdk_pool_handle,
                                       sdk_wallet_steward,
                                       tconf,
                                       tdir,
                                       allPluginsPath):
    '''
    One node restart and in catchup receive Ledger Status without protocol
    version from the one of nodes in pool.
    '''
    node_to_disconnect = txnPoolNodeSet[-1]
    break_node = txnPoolNodeSet[0]

    sdk_send_random_and_check(looper, txnPoolNodeSet,
                              sdk_pool_handle, sdk_wallet_steward, 5)

    original_get_ledger_status = break_node.getLedgerStatus

    # Path the method getLedgerStatus to
    # get_ledger_status_without_protocol_version for sending ledger status
    # without protocol version.

    def get_ledger_status_without_protocol_version(ledgerId: int):
        original_ledger_status = original_get_ledger_status(ledgerId)
        return CustomLedgerStatus(original_ledger_status.ledgerId,
                                  original_ledger_status.txnSeqNo,
                                  original_ledger_status.viewNo,
                                  original_ledger_status.ppSeqNo,
                                  original_ledger_status.merkleRoot)

    break_node.getLedgerStatus = get_ledger_status_without_protocol_version

    # restart node
    disconnect_node_and_ensure_disconnected(looper,
                                            txnPoolNodeSet,
                                            node_to_disconnect)
    looper.removeProdable(name=node_to_disconnect.name)
    sdk_send_random_and_check(looper, txnPoolNodeSet,
                              sdk_pool_handle, sdk_wallet_steward,
                              2)

    # add node_to_disconnect to pool
    node_to_disconnect = start_stopped_node(node_to_disconnect, looper, tconf,
                                            tdir, allPluginsPath)
    txnPoolNodeSet[-1] = node_to_disconnect
    looper.run(checkNodesConnected(txnPoolNodeSet))
    waitNodeDataEquality(looper, node_to_disconnect, *txnPoolNodeSet)
    # check discarding a Ledger Statuses from the break_node for all ledgers
    assert countDiscarded(node_to_disconnect,
                          'invalid replied message structure') >= 3
    sdk_send_random_and_check(looper, txnPoolNodeSet,
                              sdk_pool_handle, sdk_wallet_steward, 5)
    waitNodeDataEquality(looper, node_to_disconnect, *txnPoolNodeSet)


class CustomLedgerStatus(MessageBase):
    """
    LedgerStatus class without protocol version
    """
    typename = LEDGER_STATUS
    schema = (
        (f.LEDGER_ID.nm, LedgerIdField()),
        (f.TXN_SEQ_NO.nm, NonNegativeNumberField()),
        (f.VIEW_NO.nm, NonNegativeNumberField(nullable=True)),
        (f.PP_SEQ_NO.nm, NonNegativeNumberField(nullable=True)),
        (f.MERKLE_ROOT.nm, MerkleRootField())
    )
{'fraction_non_alphanumeric': 0.05342028583321771, 'fraction_numerical': 0.001803801859303455, 'mean_word_length': 2.344779582366589, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 32, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '531166', 'n_tokens_mistral': 2096, 'n_tokens_neox': 2049, 'n_words': 342}