github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/integration/sawtooth_integration/tests/test_namespace_restriction.py (about)

     1  # Copyright 2017 Intel Corporation
     2  #
     3  # Licensed under the Apache License, Version 2.0 (the "License");
     4  # you may not use this file except in compliance with the License.
     5  # You may obtain a copy of the License at
     6  #
     7  #     http://www.apache.org/licenses/LICENSE-2.0
     8  #
     9  # Unless required by applicable law or agreed to in writing, software
    10  # distributed under the License is distributed on an "AS IS" BASIS,
    11  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  # See the License for the specific language governing permissions and
    13  # limitations under the License.
    14  # ------------------------------------------------------------------------------
    15  
    16  import unittest
    17  import logging
    18  import json
    19  import subprocess
    20  import shlex
    21  import urllib.request
    22  import urllib.error
    23  import base64
    24  
    25  from sawtooth_block_info.common import CONFIG_ADDRESS
    26  from sawtooth_block_info.common import create_block_address
    27  from sawtooth_block_info.protobuf.block_info_pb2 import BlockInfoConfig
    28  from sawtooth_block_info.protobuf.block_info_pb2 import BlockInfo
    29  
    30  from sawtooth_intkey.intkey_message_factory import IntkeyMessageFactory
    31  from sawtooth_integration.tests.integration_tools import wait_for_rest_apis
    32  
    33  LOGGER = logging.getLogger(__name__)
    34  LOGGER.setLevel(logging.INFO)
    35  
    36  XO_PREFIX = '5b7349'
    37  WAIT = 300
    38  
    39  
    40  def get_blocks():
    41      response = query_rest_api('/blocks')
    42      return response['data']
    43  
    44  
    45  def get_block_info_config():
    46      bic = BlockInfoConfig()
    47      bic.ParseFromString(get_state(CONFIG_ADDRESS))
    48      return bic
    49  
    50  
    51  def get_block_info(block_num):
    52      bi = BlockInfo()
    53      bi.ParseFromString(get_state(create_block_address(block_num)))
    54      return bi
    55  
    56  
    57  def get_state(address):
    58      response = query_rest_api('/state/%s' % address)
    59      return base64.b64decode(response['data'])
    60  
    61  
    62  def get_state_by_prefix(prefix):
    63      response = query_rest_api('/state?address=' + prefix)
    64      return response['data']
    65  
    66  
    67  def get_xo_state():
    68      state = get_state_by_prefix(XO_PREFIX)
    69      return state
    70  
    71  
    72  def post_batch(batch):
    73      headers = {'Content-Type': 'application/octet-stream'}
    74      response = query_rest_api(
    75          '/batches', data=batch, headers=headers)
    76      response = submit_request('{}'.format(response['link']))
    77      return response
    78  
    79  
    80  def query_rest_api(suffix='', data=None, headers=None):
    81      if headers is None:
    82          headers = {}
    83      url = 'http://rest-api:8008' + suffix
    84      return submit_request(urllib.request.Request(url, data, headers))
    85  
    86  
    87  def submit_request(request):
    88      response = urllib.request.urlopen(request).read().decode('utf-8')
    89      return json.loads(response)
    90  
    91  
    92  def make_batches(keys):
    93      imf = IntkeyMessageFactory()
    94      return [imf.create_batch([('set', k, 0)]) for k in keys]
    95  
    96  
    97  def send_xo_cmd(cmd_str):
    98      LOGGER.info('Sending xo cmd: %s', cmd_str)
    99      subprocess.run(
   100          shlex.split(cmd_str),
   101          stdout=subprocess.PIPE,
   102          stderr=subprocess.PIPE,
   103          check=True)
   104  
   105  
   106  class TestNamespaceRestriction(unittest.TestCase):
   107  
   108      @classmethod
   109      def setUpClass(cls):
   110          wait_for_rest_apis(['rest-api:8008'])
   111  
   112      def test_namespace_restriction(self):
   113          """
   114          Tests that namespaces stored on-chain are enforced by the
   115          validators. According to the sawtooth_settings declared in the docker
   116          compose file, the transaciton families are expected to behave
   117          as follows:
   118          - block_info transactions are allowed
   119          - intkey transactions are banned
   120          - xo transactions are allowed
   121          """
   122          batches = make_batches('abcdef')
   123  
   124          send_xo_cmd('sawtooth keygen')
   125  
   126          xo_cmds = [
   127              'xo create game',
   128              'xo take game 5',
   129              'xo take game 5',
   130              'xo take game 9',
   131              'xo create game',
   132              'xo take game 4',
   133          ]
   134  
   135          # Assert all block info transactions are committed
   136          for i, batch in enumerate(batches):
   137              post_batch(batch)
   138              send_xo_cmd('{} --url {} --wait {}'.format(
   139                  xo_cmds[i],
   140                  'http://rest-api:8008',
   141                  WAIT))
   142              block_info = get_block_info(i)
   143              self.assertEqual(block_info.block_num, i)
   144  
   145          # Assert block info batches are first in the block and
   146          # that any other batch is of the xo family
   147          for block in get_blocks()[:-1]:
   148              LOGGER.debug(block['header']['block_num'])
   149              family_name = \
   150                  block['batches'][0]['transactions'][0]['header']['family_name']
   151              self.assertEqual(family_name, 'block_info')
   152              for batch in block['batches'][1:]:
   153                  self.assertEqual(
   154                      batch['transactions'][0]['header']['family_name'], 'xo')