This repository has been archived by the owner on Feb 1, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 766
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Onchain namespace permission checked by validator
The goal is to provide a mechanism to indicate to the blockchain/network the namespaces transaction families are allowed to write to and enforce it. This provides a way to implement a namespace permissioning mechanism. This is essential to allocate certain namespace to certain transaction families and prevent transactions to write to addresses they are not allowed to. For every transaction processed by the validator, it verifies that the outputs of the transaction are prefixed with one of the namespace listed by the transaction family it belongs to. The namespaces are indicated onchain with the settings transaction family. If no namespaces field is indicated in the onchain settings then it artificially declare an empty prefix namespace such that any output listed is valid. Therefore the change proposed is backward compatible. The new feature is tested by injecting block_info, running some intkey transactions and declaring valid namespace for block_info and *invalid* namespaces for intkey such that when blocks are validated it only includes block_info transactions. Signed-off-by: Benoit Razet <benoit.razet@pokitdok.com>
- Loading branch information
Benoit Razet
committed
Nov 16, 2017
1 parent
0403759
commit 94a66d8
Showing
4 changed files
with
267 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
119 changes: 119 additions & 0 deletions
119
integration/sawtooth_integration/docker/test_namespace_permission.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
# Copyright 2017 Intel Corporation | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# ------------------------------------------------------------------------------ | ||
|
||
version: "2.1" | ||
|
||
services: | ||
|
||
settings-tp: | ||
image: sawtooth-settings-tp:$ISOLATION_ID | ||
volumes: | ||
- $SAWTOOTH_CORE:/project/sawtooth-core | ||
expose: | ||
- 4004 | ||
depends_on: | ||
- validator | ||
command: settings-tp -vv -C tcp://validator:4004 | ||
stop_signal: SIGKILL | ||
|
||
intkey-tp-python: | ||
image: sawtooth-intkey-tp-python:$ISOLATION_ID | ||
volumes: | ||
- $SAWTOOTH_CORE:/project/sawtooth-core | ||
expose: | ||
- 4004 | ||
depends_on: | ||
- validator | ||
command: intkey-tp-python -vvv -C tcp://validator:4004 | ||
stop_signal: SIGKILL | ||
|
||
block-info-tp: | ||
image: sawtooth-block-info-tp:$ISOLATION_ID | ||
volumes: | ||
- $SAWTOOTH_CORE:/project/sawtooth-core | ||
expose: | ||
- 4004 | ||
depends_on: | ||
- validator | ||
command: block-info-tp -v -C tcp://validator:4004 | ||
stop_signal: SIGKILL | ||
|
||
validator: | ||
image: sawtooth-validator:$ISOLATION_ID | ||
volumes: | ||
- $SAWTOOTH_CORE:/project/sawtooth-core | ||
expose: | ||
- 4004 | ||
- 8800 | ||
# start the validator with an empty genesis batch | ||
command: "bash -c \"\ | ||
sawadm keygen && \ | ||
sawset genesis \ | ||
-k /etc/sawtooth/keys/validator.priv \ | ||
-o config-genesis.batch && \ | ||
sawset proposal create \ | ||
-k /etc/sawtooth/keys/validator.priv \ | ||
sawtooth.validator.transaction_families='[{\\\"family\\\": \\\"block_info\\\", \\\"version\\\": \\\"1.0\\\", \\\"namespaces\\\": [\\\"00b10c\\\"]}, {\\\"family\\\": \\\"intkey\\\", \\\"version\\\": \\\"1.0\\\", \\\"namespaces\\\": [\\\"1cf125\\\",\\\"1cf127\\\"]}, {\\\"family\\\":\\\"sawtooth_settings\\\", \\\"version\\\":\\\"1.0\\\", \\\"encoding\\\":\\\"application/protobuf\\\"}]' \ | ||
-o config_transaction_families.batch && \ | ||
sawset proposal create \ | ||
-k /etc/sawtooth/keys/validator.priv \ | ||
sawtooth.validator.batch_injectors=block_info \ | ||
'sawtooth.validator.block_validation_rules=NofX:1,block_info;XatY:block_info,0;local:0' \ | ||
-o config.batch && \ | ||
sawadm genesis \ | ||
config-genesis.batch config_transaction_families.batch config.batch && \ | ||
sawtooth-validator --endpoint tcp://validator:8800 -vv \ | ||
--bind component:tcp://eth0:4004 \ | ||
--bind network:tcp://eth0:8800 \ | ||
\"" | ||
environment: | ||
PYTHONPATH: "/project/sawtooth-core/families/block_info" | ||
stop_signal: SIGKILL | ||
|
||
rest-api: | ||
image: sawtooth-rest-api:$ISOLATION_ID | ||
volumes: | ||
- $SAWTOOTH_CORE:/project/sawtooth-core | ||
expose: | ||
- 4004 | ||
- 8080 | ||
depends_on: | ||
- validator | ||
command: sawtooth-rest-api -v --connect tcp://validator:4004 --bind rest-api:8080 | ||
stop_signal: SIGKILL | ||
|
||
test-namespace-permission: | ||
image: sawtooth-dev-python:$ISOLATION_ID | ||
volumes: | ||
- $SAWTOOTH_CORE:/project/sawtooth-core | ||
expose: | ||
- 8080 | ||
depends_on: | ||
- validator | ||
- rest-api | ||
command: "bash -c \"\ | ||
nose2-3 \ | ||
-c /project/sawtooth-core/integration/sawtooth_integration/nose2.cfg \ | ||
-v \ | ||
-s /project/sawtooth-core/integration/sawtooth_integration/tests \ | ||
test_namespace_permission.TestNamespacePermission \ | ||
\"" | ||
stop_signal: SIGKILL | ||
environment: | ||
PYTHONPATH: "/project/sawtooth-core/sdk/python:\ | ||
/project/sawtooth-core/sdk/examples/intkey_python:\ | ||
/project/sawtooth-core/families/block_info:\ | ||
/project/sawtooth-core/integration:\ | ||
/project/sawtooth-core/signing" |
104 changes: 104 additions & 0 deletions
104
integration/sawtooth_integration/tests/test_namespace_permission.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
# Copyright 2017 Intel Corporation | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# ------------------------------------------------------------------------------ | ||
|
||
import unittest | ||
import logging | ||
import json | ||
import urllib.request | ||
import urllib.error | ||
import base64 | ||
import time | ||
|
||
from sawtooth_block_info.common import CONFIG_ADDRESS | ||
from sawtooth_block_info.common import create_block_address | ||
from sawtooth_block_info.protobuf.block_info_pb2 import BlockInfoConfig | ||
from sawtooth_block_info.protobuf.block_info_pb2 import BlockInfo | ||
|
||
from sawtooth_intkey.intkey_message_factory import IntkeyMessageFactory | ||
|
||
|
||
LOGGER = logging.getLogger(__name__) | ||
LOGGER.setLevel(logging.INFO) | ||
|
||
|
||
def get_blocks(): | ||
response = query_rest_api('/blocks') | ||
return response['data'] | ||
|
||
|
||
def get_block_info_config(): | ||
bic = BlockInfoConfig() | ||
bic.ParseFromString(get_state(CONFIG_ADDRESS)) | ||
return bic | ||
|
||
|
||
def get_block_info(block_num): | ||
bi = BlockInfo() | ||
bi.ParseFromString(get_state(create_block_address(block_num))) | ||
return bi | ||
|
||
|
||
def get_state(address): | ||
response = query_rest_api('/state/%s' % address) | ||
return base64.b64decode(response['data']) | ||
|
||
|
||
def post_batch(batch): | ||
headers = {'Content-Type': 'application/octet-stream'} | ||
response = query_rest_api( | ||
'/batches', data=batch, headers=headers) | ||
response = submit_request('{}'.format(response['link'])) | ||
return response | ||
|
||
|
||
def query_rest_api(suffix='', data=None, headers={}): | ||
url = 'http://rest-api:8080' + suffix | ||
return submit_request(urllib.request.Request(url, data, headers)) | ||
|
||
|
||
def submit_request(request): | ||
response = urllib.request.urlopen(request).read().decode('utf-8') | ||
return json.loads(response) | ||
|
||
|
||
def make_batches(keys): | ||
imf = IntkeyMessageFactory() | ||
return [imf.create_batch([('set', k, 0)]) for k in keys] | ||
|
||
class TestNamespacePermission(unittest.TestCase): | ||
def test_namespace_permission(self): | ||
"""Tests that namespace permission onchain are letting block_info | ||
transactions be injected and preventing intkey transactions to | ||
be validated. | ||
""" | ||
batches = make_batches('abcd') | ||
|
||
# Assert all block info transactions are committed | ||
for i in range(len(batches)): | ||
post_batch(batches[i]) | ||
time.sleep(1) | ||
block_info = get_block_info(i) | ||
self.assertEqual(block_info.block_num, i) | ||
|
||
|
||
# Assert block info batches are first in the block and | ||
# no other batch is included | ||
for block in get_blocks()[:-1]: | ||
print(block['header']['block_num']) | ||
family_name = \ | ||
block['batches'][0]['transactions'][0]['header']['family_name'] | ||
self.assertEqual(family_name, 'block_info') | ||
self.assertEqual(len(block['batches']), 1) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters