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')