From c701cb5128f8b6c0c23ddcec4ced2508040cbf70 Mon Sep 17 00:00:00 2001 From: jeffgarratt Date: Wed, 11 Jan 2017 14:14:55 -0500 Subject: [PATCH] [FAB-1141] Adding channel create to bootstrap Adds the channel create and join process to the bootstrap process. Changed from RSA 2048 to ECDSA curve=NIST384p for signing keys. Fixed typo in orderer base docker compose file for genesismethod. Fixed issues with genisis block created for BDD. Regenerated several proto files. Removed reference to membersvc from docker compose files. Added absMaxBytes to Batchsize for genesis block creation. Change-Id: If077d3725e6edc0ba3dfe2dd6d2cf66ed255592b Signed-off-by: jeffgarratt --- bddtests/common/common_pb2.py | 247 +++++++++++++++++++--- bddtests/common/common_pb2_grpc.py | 4 + bddtests/common/configuration_pb2.py | 128 ++++++----- bddtests/common/configuration_pb2_grpc.py | 4 + bddtests/common/msp_principal_pb2.py | 234 ++++++++++++++++++++ bddtests/common/msp_principal_pb2_grpc.py | 4 + bddtests/compose-defaults.yml | 3 - bddtests/docker-compose-next-4.yml | 9 - bddtests/docker-compose-next.yml | 5 - bddtests/docker-compose-orderer-base.yml | 1 + bddtests/features/bootstrap.feature | 73 ++++++- bddtests/orderer/configuration_pb2.py | 35 +-- bddtests/steps/bootstrap_impl.py | 151 ++++++++++++- bddtests/steps/bootstrap_util.py | 195 ++++++++++++++--- bddtests/steps/compose.py | 10 +- bddtests/steps/orderer_impl.py | 8 +- bddtests/steps/orderer_util.py | 62 +++--- 17 files changed, 970 insertions(+), 203 deletions(-) create mode 100644 bddtests/common/common_pb2_grpc.py create mode 100644 bddtests/common/configuration_pb2_grpc.py create mode 100644 bddtests/common/msp_principal_pb2.py create mode 100644 bddtests/common/msp_principal_pb2_grpc.py diff --git a/bddtests/common/common_pb2.py b/bddtests/common/common_pb2.py index d1ba5c67ff6..f1f681c77b2 100644 --- a/bddtests/common/common_pb2.py +++ b/bddtests/common/common_pb2.py @@ -21,7 +21,7 @@ name='common/common.proto', package='common', syntax='proto3', - serialized_pb=_b('\n\x13\x63ommon/common.proto\x12\x06\x63ommon\x1a\x1fgoogle/protobuf/timestamp.proto\"d\n\x06Header\x12(\n\x0b\x63hainHeader\x18\x01 \x01(\x0b\x32\x13.common.ChainHeader\x12\x30\n\x0fsignatureHeader\x18\x02 \x01(\x0b\x32\x17.common.SignatureHeader\"\x9c\x01\n\x0b\x43hainHeader\x12\x0c\n\x04type\x18\x01 \x01(\x05\x12\x0f\n\x07version\x18\x02 \x01(\x05\x12-\n\ttimestamp\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0f\n\x07\x63hainID\x18\x04 \x01(\x0c\x12\x0c\n\x04txID\x18\x05 \x01(\t\x12\r\n\x05\x65poch\x18\x06 \x01(\x04\x12\x11\n\textension\x18\x07 \x01(\x0c\"1\n\x0fSignatureHeader\x12\x0f\n\x07\x63reator\x18\x01 \x01(\x0c\x12\r\n\x05nonce\x18\x02 \x01(\x0c\"7\n\x07Payload\x12\x1e\n\x06header\x18\x01 \x01(\x0b\x32\x0e.common.Header\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\".\n\x08\x45nvelope\x12\x0f\n\x07payload\x18\x01 \x01(\x0c\x12\x11\n\tsignature\x18\x02 \x01(\x0c\"v\n\x05\x42lock\x12#\n\x06Header\x18\x01 \x01(\x0b\x32\x13.common.BlockHeader\x12\x1f\n\x04\x44\x61ta\x18\x02 \x01(\x0b\x32\x11.common.BlockData\x12\'\n\x08Metadata\x18\x03 \x01(\x0b\x32\x15.common.BlockMetadata\"E\n\x0b\x42lockHeader\x12\x0e\n\x06Number\x18\x01 \x01(\x04\x12\x14\n\x0cPreviousHash\x18\x02 \x01(\x0c\x12\x10\n\x08\x44\x61taHash\x18\x03 \x01(\x0c\"\x19\n\tBlockData\x12\x0c\n\x04\x44\x61ta\x18\x01 \x03(\x0c\"!\n\rBlockMetadata\x12\x10\n\x08Metadata\x18\x01 \x03(\x0c*\x8b\x01\n\x06Status\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x0c\n\x07SUCCESS\x10\xc8\x01\x12\x10\n\x0b\x42\x41\x44_REQUEST\x10\x90\x03\x12\x0e\n\tFORBIDDEN\x10\x93\x03\x12\x0e\n\tNOT_FOUND\x10\x94\x03\x12\x1a\n\x15INTERNAL_SERVER_ERROR\x10\xf4\x03\x12\x18\n\x13SERVICE_UNAVAILABLE\x10\xf7\x03*j\n\nHeaderType\x12\x0b\n\x07MESSAGE\x10\x00\x12\x1d\n\x19\x43ONFIGURATION_TRANSACTION\x10\x01\x12\x16\n\x12\x43ONFIGURATION_ITEM\x10\x02\x12\x18\n\x14\x45NDORSER_TRANSACTION\x10\x03\x42-Z+github.com/hyperledger/fabric/protos/commonb\x06proto3') + serialized_pb=_b('\n\x13\x63ommon/common.proto\x12\x06\x63ommon\x1a\x1fgoogle/protobuf/timestamp.proto\"\"\n\x11LastConfiguration\x12\r\n\x05index\x18\x01 \x01(\x04\"H\n\x08Metadata\x12\r\n\x05value\x18\x01 \x01(\x0c\x12-\n\nsignatures\x18\x02 \x03(\x0b\x32\x19.common.MetadataSignature\"?\n\x11MetadataSignature\x12\x17\n\x0fsignatureHeader\x18\x01 \x01(\x0c\x12\x11\n\tsignature\x18\x02 \x01(\x0c\"d\n\x06Header\x12(\n\x0b\x63hainHeader\x18\x01 \x01(\x0b\x32\x13.common.ChainHeader\x12\x30\n\x0fsignatureHeader\x18\x02 \x01(\x0b\x32\x17.common.SignatureHeader\"\x9c\x01\n\x0b\x43hainHeader\x12\x0c\n\x04type\x18\x01 \x01(\x05\x12\x0f\n\x07version\x18\x02 \x01(\x05\x12-\n\ttimestamp\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0f\n\x07\x63hainID\x18\x04 \x01(\t\x12\x0c\n\x04txID\x18\x05 \x01(\t\x12\r\n\x05\x65poch\x18\x06 \x01(\x04\x12\x11\n\textension\x18\x07 \x01(\x0c\"1\n\x0fSignatureHeader\x12\x0f\n\x07\x63reator\x18\x01 \x01(\x0c\x12\r\n\x05nonce\x18\x02 \x01(\x0c\"7\n\x07Payload\x12\x1e\n\x06header\x18\x01 \x01(\x0b\x32\x0e.common.Header\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\".\n\x08\x45nvelope\x12\x0f\n\x07payload\x18\x01 \x01(\x0c\x12\x11\n\tsignature\x18\x02 \x01(\x0c\"v\n\x05\x42lock\x12#\n\x06Header\x18\x01 \x01(\x0b\x32\x13.common.BlockHeader\x12\x1f\n\x04\x44\x61ta\x18\x02 \x01(\x0b\x32\x11.common.BlockData\x12\'\n\x08Metadata\x18\x03 \x01(\x0b\x32\x15.common.BlockMetadata\"E\n\x0b\x42lockHeader\x12\x0e\n\x06Number\x18\x01 \x01(\x04\x12\x14\n\x0cPreviousHash\x18\x02 \x01(\x0c\x12\x10\n\x08\x44\x61taHash\x18\x03 \x01(\x0c\"\x19\n\tBlockData\x12\x0c\n\x04\x44\x61ta\x18\x01 \x03(\x0c\"!\n\rBlockMetadata\x12\x10\n\x08Metadata\x18\x01 \x03(\x0c*\xaa\x01\n\x06Status\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x0c\n\x07SUCCESS\x10\xc8\x01\x12\x10\n\x0b\x42\x41\x44_REQUEST\x10\x90\x03\x12\x0e\n\tFORBIDDEN\x10\x93\x03\x12\x0e\n\tNOT_FOUND\x10\x94\x03\x12\x1d\n\x18REQUEST_ENTITY_TOO_LARGE\x10\x9d\x03\x12\x1a\n\x15INTERNAL_SERVER_ERROR\x10\xf4\x03\x12\x18\n\x13SERVICE_UNAVAILABLE\x10\xf7\x03*\x9a\x01\n\nHeaderType\x12\x0b\n\x07MESSAGE\x10\x00\x12\x1d\n\x19\x43ONFIGURATION_TRANSACTION\x10\x01\x12\x16\n\x12\x43ONFIGURATION_ITEM\x10\x02\x12\x18\n\x14\x45NDORSER_TRANSACTION\x10\x03\x12\x17\n\x13ORDERER_TRANSACTION\x10\x04\x12\x15\n\x11\x44\x45LIVER_SEEK_INFO\x10\x05*U\n\x12\x42lockMetadataIndex\x12\x0e\n\nSIGNATURES\x10\x00\x12\x16\n\x12LAST_CONFIGURATION\x10\x01\x12\x17\n\x13TRANSACTIONS_FILTER\x10\x02\x42-Z+github.com/hyperledger/fabric/protos/commonb\x06proto3') , dependencies=[google_dot_protobuf_dot_timestamp__pb2.DESCRIPTOR,]) _sym_db.RegisterFileDescriptor(DESCRIPTOR) @@ -53,18 +53,22 @@ options=None, type=None), _descriptor.EnumValueDescriptor( - name='INTERNAL_SERVER_ERROR', index=5, number=500, + name='REQUEST_ENTITY_TOO_LARGE', index=5, number=413, options=None, type=None), _descriptor.EnumValueDescriptor( - name='SERVICE_UNAVAILABLE', index=6, number=503, + name='INTERNAL_SERVER_ERROR', index=6, number=500, + options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='SERVICE_UNAVAILABLE', index=7, number=503, options=None, type=None), ], containing_type=None, options=None, - serialized_start=735, - serialized_end=874, + serialized_start=910, + serialized_end=1080, ) _sym_db.RegisterEnumDescriptor(_STATUS) @@ -91,29 +95,177 @@ name='ENDORSER_TRANSACTION', index=3, number=3, options=None, type=None), + _descriptor.EnumValueDescriptor( + name='ORDERER_TRANSACTION', index=4, number=4, + options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='DELIVER_SEEK_INFO', index=5, number=5, + options=None, + type=None), ], containing_type=None, options=None, - serialized_start=876, - serialized_end=982, + serialized_start=1083, + serialized_end=1237, ) _sym_db.RegisterEnumDescriptor(_HEADERTYPE) HeaderType = enum_type_wrapper.EnumTypeWrapper(_HEADERTYPE) +_BLOCKMETADATAINDEX = _descriptor.EnumDescriptor( + name='BlockMetadataIndex', + full_name='common.BlockMetadataIndex', + filename=None, + file=DESCRIPTOR, + values=[ + _descriptor.EnumValueDescriptor( + name='SIGNATURES', index=0, number=0, + options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='LAST_CONFIGURATION', index=1, number=1, + options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='TRANSACTIONS_FILTER', index=2, number=2, + options=None, + type=None), + ], + containing_type=None, + options=None, + serialized_start=1239, + serialized_end=1324, +) +_sym_db.RegisterEnumDescriptor(_BLOCKMETADATAINDEX) + +BlockMetadataIndex = enum_type_wrapper.EnumTypeWrapper(_BLOCKMETADATAINDEX) UNKNOWN = 0 SUCCESS = 200 BAD_REQUEST = 400 FORBIDDEN = 403 NOT_FOUND = 404 +REQUEST_ENTITY_TOO_LARGE = 413 INTERNAL_SERVER_ERROR = 500 SERVICE_UNAVAILABLE = 503 MESSAGE = 0 CONFIGURATION_TRANSACTION = 1 CONFIGURATION_ITEM = 2 ENDORSER_TRANSACTION = 3 +ORDERER_TRANSACTION = 4 +DELIVER_SEEK_INFO = 5 +SIGNATURES = 0 +LAST_CONFIGURATION = 1 +TRANSACTIONS_FILTER = 2 +_LASTCONFIGURATION = _descriptor.Descriptor( + name='LastConfiguration', + full_name='common.LastConfiguration', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='index', full_name='common.LastConfiguration.index', index=0, + number=1, type=4, cpp_type=4, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=64, + serialized_end=98, +) + + +_METADATA = _descriptor.Descriptor( + name='Metadata', + full_name='common.Metadata', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='value', full_name='common.Metadata.value', index=0, + number=1, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=_b(""), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='signatures', full_name='common.Metadata.signatures', index=1, + number=2, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=100, + serialized_end=172, +) + + +_METADATASIGNATURE = _descriptor.Descriptor( + name='MetadataSignature', + full_name='common.MetadataSignature', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='signatureHeader', full_name='common.MetadataSignature.signatureHeader', index=0, + number=1, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=_b(""), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='signature', full_name='common.MetadataSignature.signature', index=1, + number=2, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=_b(""), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=174, + serialized_end=237, +) + + _HEADER = _descriptor.Descriptor( name='Header', full_name='common.Header', @@ -147,8 +299,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=64, - serialized_end=164, + serialized_start=239, + serialized_end=339, ) @@ -182,8 +334,8 @@ options=None), _descriptor.FieldDescriptor( name='chainID', full_name='common.ChainHeader.chainID', index=3, - number=4, type=12, cpp_type=9, label=1, - has_default_value=False, default_value=_b(""), + number=4, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), @@ -220,8 +372,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=167, - serialized_end=323, + serialized_start=342, + serialized_end=498, ) @@ -258,8 +410,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=325, - serialized_end=374, + serialized_start=500, + serialized_end=549, ) @@ -296,8 +448,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=376, - serialized_end=431, + serialized_start=551, + serialized_end=606, ) @@ -334,8 +486,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=433, - serialized_end=479, + serialized_start=608, + serialized_end=654, ) @@ -379,8 +531,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=481, - serialized_end=599, + serialized_start=656, + serialized_end=774, ) @@ -424,8 +576,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=601, - serialized_end=670, + serialized_start=776, + serialized_end=845, ) @@ -455,8 +607,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=672, - serialized_end=697, + serialized_start=847, + serialized_end=872, ) @@ -486,10 +638,11 @@ extension_ranges=[], oneofs=[ ], - serialized_start=699, - serialized_end=732, + serialized_start=874, + serialized_end=907, ) +_METADATA.fields_by_name['signatures'].message_type = _METADATASIGNATURE _HEADER.fields_by_name['chainHeader'].message_type = _CHAINHEADER _HEADER.fields_by_name['signatureHeader'].message_type = _SIGNATUREHEADER _CHAINHEADER.fields_by_name['timestamp'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP @@ -497,6 +650,9 @@ _BLOCK.fields_by_name['Header'].message_type = _BLOCKHEADER _BLOCK.fields_by_name['Data'].message_type = _BLOCKDATA _BLOCK.fields_by_name['Metadata'].message_type = _BLOCKMETADATA +DESCRIPTOR.message_types_by_name['LastConfiguration'] = _LASTCONFIGURATION +DESCRIPTOR.message_types_by_name['Metadata'] = _METADATA +DESCRIPTOR.message_types_by_name['MetadataSignature'] = _METADATASIGNATURE DESCRIPTOR.message_types_by_name['Header'] = _HEADER DESCRIPTOR.message_types_by_name['ChainHeader'] = _CHAINHEADER DESCRIPTOR.message_types_by_name['SignatureHeader'] = _SIGNATUREHEADER @@ -508,6 +664,28 @@ DESCRIPTOR.message_types_by_name['BlockMetadata'] = _BLOCKMETADATA DESCRIPTOR.enum_types_by_name['Status'] = _STATUS DESCRIPTOR.enum_types_by_name['HeaderType'] = _HEADERTYPE +DESCRIPTOR.enum_types_by_name['BlockMetadataIndex'] = _BLOCKMETADATAINDEX + +LastConfiguration = _reflection.GeneratedProtocolMessageType('LastConfiguration', (_message.Message,), dict( + DESCRIPTOR = _LASTCONFIGURATION, + __module__ = 'common.common_pb2' + # @@protoc_insertion_point(class_scope:common.LastConfiguration) + )) +_sym_db.RegisterMessage(LastConfiguration) + +Metadata = _reflection.GeneratedProtocolMessageType('Metadata', (_message.Message,), dict( + DESCRIPTOR = _METADATA, + __module__ = 'common.common_pb2' + # @@protoc_insertion_point(class_scope:common.Metadata) + )) +_sym_db.RegisterMessage(Metadata) + +MetadataSignature = _reflection.GeneratedProtocolMessageType('MetadataSignature', (_message.Message,), dict( + DESCRIPTOR = _METADATASIGNATURE, + __module__ = 'common.common_pb2' + # @@protoc_insertion_point(class_scope:common.MetadataSignature) + )) +_sym_db.RegisterMessage(MetadataSignature) Header = _reflection.GeneratedProtocolMessageType('Header', (_message.Message,), dict( DESCRIPTOR = _HEADER, @@ -575,9 +753,14 @@ DESCRIPTOR.has_options = True DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('Z+github.com/hyperledger/fabric/protos/common')) -import grpc -from grpc.beta import implementations as beta_implementations -from grpc.beta import interfaces as beta_interfaces -from grpc.framework.common import cardinality -from grpc.framework.interfaces.face import utilities as face_utilities +try: + # THESE ELEMENTS WILL BE DEPRECATED. + # Please use the generated *_pb2_grpc.py files instead. + import grpc + from grpc.framework.common import cardinality + from grpc.framework.interfaces.face import utilities as face_utilities + from grpc.beta import implementations as beta_implementations + from grpc.beta import interfaces as beta_interfaces +except ImportError: + pass # @@protoc_insertion_point(module_scope) diff --git a/bddtests/common/common_pb2_grpc.py b/bddtests/common/common_pb2_grpc.py new file mode 100644 index 00000000000..c374a4d7d5b --- /dev/null +++ b/bddtests/common/common_pb2_grpc.py @@ -0,0 +1,4 @@ +import grpc +from grpc.framework.common import cardinality +from grpc.framework.interfaces.face import utilities as face_utilities + diff --git a/bddtests/common/configuration_pb2.py b/bddtests/common/configuration_pb2.py index c906f23f157..aaeaf98a4f7 100644 --- a/bddtests/common/configuration_pb2.py +++ b/bddtests/common/configuration_pb2.py @@ -20,7 +20,7 @@ name='common/configuration.proto', package='common', syntax='proto3', - serialized_pb=_b('\n\x1a\x63ommon/configuration.proto\x12\x06\x63ommon\x1a\x13\x63ommon/common.proto\"G\n\x15\x43onfigurationEnvelope\x12.\n\x05Items\x18\x01 \x03(\x0b\x32\x1f.common.SignedConfigurationItem\"h\n\x17SignedConfigurationItem\x12\x19\n\x11\x43onfigurationItem\x18\x01 \x01(\x0c\x12\x32\n\nSignatures\x18\x02 \x03(\x0b\x32\x1e.common.ConfigurationSignature\"\x86\x02\n\x11\x43onfigurationItem\x12#\n\x06Header\x18\x01 \x01(\x0b\x32\x13.common.ChainHeader\x12\x39\n\x04Type\x18\x02 \x01(\x0e\x32+.common.ConfigurationItem.ConfigurationType\x12\x14\n\x0cLastModified\x18\x03 \x01(\x04\x12\x1a\n\x12ModificationPolicy\x18\x04 \x01(\t\x12\x0b\n\x03Key\x18\x05 \x01(\t\x12\r\n\x05Value\x18\x06 \x01(\x0c\"C\n\x11\x43onfigurationType\x12\n\n\x06Policy\x10\x00\x12\t\n\x05\x43hain\x10\x01\x12\x0b\n\x07Orderer\x10\x02\x12\n\n\x06\x46\x61\x62ric\x10\x03\"D\n\x16\x43onfigurationSignature\x12\x17\n\x0fsignatureHeader\x18\x01 \x01(\x0c\x12\x11\n\tsignature\x18\x02 \x01(\x0c\"\'\n\x0f\x43\x65rtificateList\x12\x14\n\x0c\x43\x65rtificates\x18\x01 \x03(\x0c\"L\n\x06Policy\x12:\n\x0fSignaturePolicy\x18\x01 \x01(\x0b\x32\x1f.common.SignaturePolicyEnvelopeH\x00\x42\x06\n\x04Type\"g\n\x17SignaturePolicyEnvelope\x12\x0f\n\x07Version\x18\x01 \x01(\x05\x12\'\n\x06Policy\x18\x02 \x01(\x0b\x32\x17.common.SignaturePolicy\x12\x12\n\nIdentities\x18\x03 \x03(\x0c\"\x9d\x01\n\x0fSignaturePolicy\x12\x12\n\x08SignedBy\x18\x01 \x01(\x05H\x00\x12.\n\x04\x46rom\x18\x02 \x01(\x0b\x32\x1e.common.SignaturePolicy.NOutOfH\x00\x1a>\n\x06NOutOf\x12\t\n\x01N\x18\x01 \x01(\x05\x12)\n\x08Policies\x18\x02 \x03(\x0b\x32\x17.common.SignaturePolicyB\x06\n\x04TypeB-Z+github.com/hyperledger/fabric/protos/commonb\x06proto3') + serialized_pb=_b('\n\x1a\x63ommon/configuration.proto\x12\x06\x63ommon\x1a\x13\x63ommon/common.proto\"G\n\x15\x43onfigurationEnvelope\x12.\n\x05Items\x18\x01 \x03(\x0b\x32\x1f.common.SignedConfigurationItem\"h\n\x17SignedConfigurationItem\x12\x19\n\x11\x43onfigurationItem\x18\x01 \x01(\x0c\x12\x32\n\nSignatures\x18\x02 \x03(\x0b\x32\x1e.common.ConfigurationSignature\"\x84\x02\n\x11\x43onfigurationItem\x12#\n\x06Header\x18\x01 \x01(\x0b\x32\x13.common.ChainHeader\x12\x39\n\x04Type\x18\x02 \x01(\x0e\x32+.common.ConfigurationItem.ConfigurationType\x12\x14\n\x0cLastModified\x18\x03 \x01(\x04\x12\x1a\n\x12ModificationPolicy\x18\x04 \x01(\t\x12\x0b\n\x03Key\x18\x05 \x01(\t\x12\r\n\x05Value\x18\x06 \x01(\x0c\"A\n\x11\x43onfigurationType\x12\n\n\x06Policy\x10\x00\x12\t\n\x05\x43hain\x10\x01\x12\x0b\n\x07Orderer\x10\x02\x12\x08\n\x04Peer\x10\x03\"D\n\x16\x43onfigurationSignature\x12\x17\n\x0fsignatureHeader\x18\x01 \x01(\x0c\x12\x11\n\tsignature\x18\x02 \x01(\x0c\"Y\n\x06Policy\x12\x0c\n\x04type\x18\x01 \x01(\x05\x12\x0e\n\x06policy\x18\x02 \x01(\x0c\"1\n\nPolicyType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\r\n\tSIGNATURE\x10\x01\x12\x07\n\x03MSP\x10\x02\"g\n\x17SignaturePolicyEnvelope\x12\x0f\n\x07Version\x18\x01 \x01(\x05\x12\'\n\x06Policy\x18\x02 \x01(\x0b\x32\x17.common.SignaturePolicy\x12\x12\n\nIdentities\x18\x03 \x03(\x0c\"\x9d\x01\n\x0fSignaturePolicy\x12\x12\n\x08SignedBy\x18\x01 \x01(\x05H\x00\x12.\n\x04\x46rom\x18\x02 \x01(\x0b\x32\x1e.common.SignaturePolicy.NOutOfH\x00\x1a>\n\x06NOutOf\x12\t\n\x01N\x18\x01 \x01(\x05\x12)\n\x08Policies\x18\x02 \x03(\x0b\x32\x17.common.SignaturePolicyB\x06\n\x04TypeB-Z+github.com/hyperledger/fabric/protos/commonb\x06proto3') , dependencies=[common_dot_common__pb2.DESCRIPTOR,]) _sym_db.RegisterFileDescriptor(DESCRIPTOR) @@ -46,17 +46,43 @@ options=None, type=None), _descriptor.EnumValueDescriptor( - name='Fabric', index=3, number=3, + name='Peer', index=3, number=3, options=None, type=None), ], containing_type=None, options=None, serialized_start=434, - serialized_end=501, + serialized_end=499, ) _sym_db.RegisterEnumDescriptor(_CONFIGURATIONITEM_CONFIGURATIONTYPE) +_POLICY_POLICYTYPE = _descriptor.EnumDescriptor( + name='PolicyType', + full_name='common.Policy.PolicyType', + filename=None, + file=DESCRIPTOR, + values=[ + _descriptor.EnumValueDescriptor( + name='UNKNOWN', index=0, number=0, + options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='SIGNATURE', index=1, number=1, + options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='MSP', index=2, number=2, + options=None, + type=None), + ], + containing_type=None, + options=None, + serialized_start=611, + serialized_end=660, +) +_sym_db.RegisterEnumDescriptor(_POLICY_POLICYTYPE) + _CONFIGURATIONENVELOPE = _descriptor.Descriptor( name='ConfigurationEnvelope', @@ -190,7 +216,7 @@ oneofs=[ ], serialized_start=239, - serialized_end=501, + serialized_end=499, ) @@ -227,53 +253,29 @@ extension_ranges=[], oneofs=[ ], - serialized_start=503, - serialized_end=571, + serialized_start=501, + serialized_end=569, ) -_CERTIFICATELIST = _descriptor.Descriptor( - name='CertificateList', - full_name='common.CertificateList', +_POLICY = _descriptor.Descriptor( + name='Policy', + full_name='common.Policy', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( - name='Certificates', full_name='common.CertificateList.Certificates', index=0, - number=1, type=12, cpp_type=9, label=3, - has_default_value=False, default_value=[], + name='type', full_name='common.Policy.type', index=0, + number=1, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=573, - serialized_end=612, -) - - -_POLICY = _descriptor.Descriptor( - name='Policy', - full_name='common.Policy', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ _descriptor.FieldDescriptor( - name='SignaturePolicy', full_name='common.Policy.SignaturePolicy', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, + name='policy', full_name='common.Policy.policy', index=1, + number=2, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=_b(""), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), @@ -282,18 +284,16 @@ ], nested_types=[], enum_types=[ + _POLICY_POLICYTYPE, ], options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ - _descriptor.OneofDescriptor( - name='Type', full_name='common.Policy.Type', - index=0, containing_type=None, fields=[]), ], - serialized_start=614, - serialized_end=690, + serialized_start=571, + serialized_end=660, ) @@ -337,8 +337,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=692, - serialized_end=795, + serialized_start=662, + serialized_end=765, ) @@ -375,8 +375,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=885, - serialized_end=947, + serialized_start=855, + serialized_end=917, ) _SIGNATUREPOLICY = _descriptor.Descriptor( @@ -415,8 +415,8 @@ name='Type', full_name='common.SignaturePolicy.Type', index=0, containing_type=None, fields=[]), ], - serialized_start=798, - serialized_end=955, + serialized_start=768, + serialized_end=925, ) _CONFIGURATIONENVELOPE.fields_by_name['Items'].message_type = _SIGNEDCONFIGURATIONITEM @@ -424,10 +424,7 @@ _CONFIGURATIONITEM.fields_by_name['Header'].message_type = common_dot_common__pb2._CHAINHEADER _CONFIGURATIONITEM.fields_by_name['Type'].enum_type = _CONFIGURATIONITEM_CONFIGURATIONTYPE _CONFIGURATIONITEM_CONFIGURATIONTYPE.containing_type = _CONFIGURATIONITEM -_POLICY.fields_by_name['SignaturePolicy'].message_type = _SIGNATUREPOLICYENVELOPE -_POLICY.oneofs_by_name['Type'].fields.append( - _POLICY.fields_by_name['SignaturePolicy']) -_POLICY.fields_by_name['SignaturePolicy'].containing_oneof = _POLICY.oneofs_by_name['Type'] +_POLICY_POLICYTYPE.containing_type = _POLICY _SIGNATUREPOLICYENVELOPE.fields_by_name['Policy'].message_type = _SIGNATUREPOLICY _SIGNATUREPOLICY_NOUTOF.fields_by_name['Policies'].message_type = _SIGNATUREPOLICY _SIGNATUREPOLICY_NOUTOF.containing_type = _SIGNATUREPOLICY @@ -442,7 +439,6 @@ DESCRIPTOR.message_types_by_name['SignedConfigurationItem'] = _SIGNEDCONFIGURATIONITEM DESCRIPTOR.message_types_by_name['ConfigurationItem'] = _CONFIGURATIONITEM DESCRIPTOR.message_types_by_name['ConfigurationSignature'] = _CONFIGURATIONSIGNATURE -DESCRIPTOR.message_types_by_name['CertificateList'] = _CERTIFICATELIST DESCRIPTOR.message_types_by_name['Policy'] = _POLICY DESCRIPTOR.message_types_by_name['SignaturePolicyEnvelope'] = _SIGNATUREPOLICYENVELOPE DESCRIPTOR.message_types_by_name['SignaturePolicy'] = _SIGNATUREPOLICY @@ -475,13 +471,6 @@ )) _sym_db.RegisterMessage(ConfigurationSignature) -CertificateList = _reflection.GeneratedProtocolMessageType('CertificateList', (_message.Message,), dict( - DESCRIPTOR = _CERTIFICATELIST, - __module__ = 'common.configuration_pb2' - # @@protoc_insertion_point(class_scope:common.CertificateList) - )) -_sym_db.RegisterMessage(CertificateList) - Policy = _reflection.GeneratedProtocolMessageType('Policy', (_message.Message,), dict( DESCRIPTOR = _POLICY, __module__ = 'common.configuration_pb2' @@ -514,9 +503,14 @@ DESCRIPTOR.has_options = True DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('Z+github.com/hyperledger/fabric/protos/common')) -import grpc -from grpc.beta import implementations as beta_implementations -from grpc.beta import interfaces as beta_interfaces -from grpc.framework.common import cardinality -from grpc.framework.interfaces.face import utilities as face_utilities +try: + # THESE ELEMENTS WILL BE DEPRECATED. + # Please use the generated *_pb2_grpc.py files instead. + import grpc + from grpc.framework.common import cardinality + from grpc.framework.interfaces.face import utilities as face_utilities + from grpc.beta import implementations as beta_implementations + from grpc.beta import interfaces as beta_interfaces +except ImportError: + pass # @@protoc_insertion_point(module_scope) diff --git a/bddtests/common/configuration_pb2_grpc.py b/bddtests/common/configuration_pb2_grpc.py new file mode 100644 index 00000000000..c374a4d7d5b --- /dev/null +++ b/bddtests/common/configuration_pb2_grpc.py @@ -0,0 +1,4 @@ +import grpc +from grpc.framework.common import cardinality +from grpc.framework.interfaces.face import utilities as face_utilities + diff --git a/bddtests/common/msp_principal_pb2.py b/bddtests/common/msp_principal_pb2.py new file mode 100644 index 00000000000..83542f955f6 --- /dev/null +++ b/bddtests/common/msp_principal_pb2.py @@ -0,0 +1,234 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: common/msp_principal.proto + +import sys +_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +from google.protobuf import descriptor_pb2 +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='common/msp_principal.proto', + package='common', + syntax='proto3', + serialized_pb=_b('\n\x1a\x63ommon/msp_principal.proto\x12\x06\x63ommon\"\xb0\x01\n\x0cMSPPrincipal\x12\x44\n\x17PrincipalClassification\x18\x01 \x01(\x0e\x32#.common.MSPPrincipal.Classification\x12\x11\n\tPrincipal\x18\x03 \x01(\x0c\"G\n\x0e\x43lassification\x12\r\n\tByMSPRole\x10\x00\x12\x16\n\x12\x42yOrganizationUnit\x10\x01\x12\x0e\n\nByIdentity\x10\x02\"M\n\x10OrganizationUnit\x12\x15\n\rMSPIdentifier\x18\x01 \x01(\t\x12\"\n\x1aOrganizationUnitIdentifier\x18\x02 \x01(\t\"q\n\x07MSPRole\x12\x15\n\rMSPIdentifier\x18\x01 \x01(\t\x12)\n\x04Role\x18\x02 \x01(\x0e\x32\x1b.common.MSPRole.MSPRoleType\"$\n\x0bMSPRoleType\x12\n\n\x06Member\x10\x00\x12\t\n\x05\x41\x64min\x10\x01\x42-Z+github.com/hyperledger/fabric/protos/commonb\x06proto3') +) +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + + + +_MSPPRINCIPAL_CLASSIFICATION = _descriptor.EnumDescriptor( + name='Classification', + full_name='common.MSPPrincipal.Classification', + filename=None, + file=DESCRIPTOR, + values=[ + _descriptor.EnumValueDescriptor( + name='ByMSPRole', index=0, number=0, + options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='ByOrganizationUnit', index=1, number=1, + options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='ByIdentity', index=2, number=2, + options=None, + type=None), + ], + containing_type=None, + options=None, + serialized_start=144, + serialized_end=215, +) +_sym_db.RegisterEnumDescriptor(_MSPPRINCIPAL_CLASSIFICATION) + +_MSPROLE_MSPROLETYPE = _descriptor.EnumDescriptor( + name='MSPRoleType', + full_name='common.MSPRole.MSPRoleType', + filename=None, + file=DESCRIPTOR, + values=[ + _descriptor.EnumValueDescriptor( + name='Member', index=0, number=0, + options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='Admin', index=1, number=1, + options=None, + type=None), + ], + containing_type=None, + options=None, + serialized_start=373, + serialized_end=409, +) +_sym_db.RegisterEnumDescriptor(_MSPROLE_MSPROLETYPE) + + +_MSPPRINCIPAL = _descriptor.Descriptor( + name='MSPPrincipal', + full_name='common.MSPPrincipal', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='PrincipalClassification', full_name='common.MSPPrincipal.PrincipalClassification', index=0, + number=1, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='Principal', full_name='common.MSPPrincipal.Principal', index=1, + number=3, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=_b(""), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + _MSPPRINCIPAL_CLASSIFICATION, + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=39, + serialized_end=215, +) + + +_ORGANIZATIONUNIT = _descriptor.Descriptor( + name='OrganizationUnit', + full_name='common.OrganizationUnit', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='MSPIdentifier', full_name='common.OrganizationUnit.MSPIdentifier', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='OrganizationUnitIdentifier', full_name='common.OrganizationUnit.OrganizationUnitIdentifier', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=217, + serialized_end=294, +) + + +_MSPROLE = _descriptor.Descriptor( + name='MSPRole', + full_name='common.MSPRole', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='MSPIdentifier', full_name='common.MSPRole.MSPIdentifier', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='Role', full_name='common.MSPRole.Role', index=1, + number=2, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + _MSPROLE_MSPROLETYPE, + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=296, + serialized_end=409, +) + +_MSPPRINCIPAL.fields_by_name['PrincipalClassification'].enum_type = _MSPPRINCIPAL_CLASSIFICATION +_MSPPRINCIPAL_CLASSIFICATION.containing_type = _MSPPRINCIPAL +_MSPROLE.fields_by_name['Role'].enum_type = _MSPROLE_MSPROLETYPE +_MSPROLE_MSPROLETYPE.containing_type = _MSPROLE +DESCRIPTOR.message_types_by_name['MSPPrincipal'] = _MSPPRINCIPAL +DESCRIPTOR.message_types_by_name['OrganizationUnit'] = _ORGANIZATIONUNIT +DESCRIPTOR.message_types_by_name['MSPRole'] = _MSPROLE + +MSPPrincipal = _reflection.GeneratedProtocolMessageType('MSPPrincipal', (_message.Message,), dict( + DESCRIPTOR = _MSPPRINCIPAL, + __module__ = 'common.msp_principal_pb2' + # @@protoc_insertion_point(class_scope:common.MSPPrincipal) + )) +_sym_db.RegisterMessage(MSPPrincipal) + +OrganizationUnit = _reflection.GeneratedProtocolMessageType('OrganizationUnit', (_message.Message,), dict( + DESCRIPTOR = _ORGANIZATIONUNIT, + __module__ = 'common.msp_principal_pb2' + # @@protoc_insertion_point(class_scope:common.OrganizationUnit) + )) +_sym_db.RegisterMessage(OrganizationUnit) + +MSPRole = _reflection.GeneratedProtocolMessageType('MSPRole', (_message.Message,), dict( + DESCRIPTOR = _MSPROLE, + __module__ = 'common.msp_principal_pb2' + # @@protoc_insertion_point(class_scope:common.MSPRole) + )) +_sym_db.RegisterMessage(MSPRole) + + +DESCRIPTOR.has_options = True +DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('Z+github.com/hyperledger/fabric/protos/common')) +try: + # THESE ELEMENTS WILL BE DEPRECATED. + # Please use the generated *_pb2_grpc.py files instead. + import grpc + from grpc.framework.common import cardinality + from grpc.framework.interfaces.face import utilities as face_utilities + from grpc.beta import implementations as beta_implementations + from grpc.beta import interfaces as beta_interfaces +except ImportError: + pass +# @@protoc_insertion_point(module_scope) diff --git a/bddtests/common/msp_principal_pb2_grpc.py b/bddtests/common/msp_principal_pb2_grpc.py new file mode 100644 index 00000000000..c374a4d7d5b --- /dev/null +++ b/bddtests/common/msp_principal_pb2_grpc.py @@ -0,0 +1,4 @@ +import grpc +from grpc.framework.common import cardinality +from grpc.framework.interfaces.face import utilities as face_utilities + diff --git a/bddtests/compose-defaults.yml b/bddtests/compose-defaults.yml index a607584b164..b81f378d7e7 100644 --- a/bddtests/compose-defaults.yml +++ b/bddtests/compose-defaults.yml @@ -21,9 +21,6 @@ services: # Use these options if coverage desired for peers #image: hyperledger/fabric-peer-coverage #command: ./peer.test --test.coverprofile=coverage.cov node start - membersrvc: - image: hyperledger/fabric-membersrvc - command: membersrvc volumes: diff --git a/bddtests/docker-compose-next-4.yml b/bddtests/docker-compose-next-4.yml index 75260795ea9..c1e9db6d4b2 100644 --- a/bddtests/docker-compose-next-4.yml +++ b/bddtests/docker-compose-next-4.yml @@ -2,11 +2,6 @@ version: "2" services: - membersrvc0: - extends: - file: compose-defaults.yml - service: membersrvc - orderer0: extends: file: docker-compose-orderer-solo.yml @@ -23,7 +18,6 @@ services: - CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer0:7050 - CORE_PEER_MSPCONFIGPATH=${PEER0_CORE_PEER_MSPCFGPATH} depends_on: - - membersrvc0 - orderer0 # ports: # - 7050:6060 @@ -39,7 +33,6 @@ services: - CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer0:7050 - CORE_PEER_MSPCONFIGPATH=${PEER1_CORE_PEER_MSPCFGPATH} depends_on: - - membersrvc0 - orderer0 - peer0 @@ -53,7 +46,6 @@ services: - CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer0:7050 - CORE_PEER_MSPCONFIGPATH=${PEER2_CORE_PEER_MSPCFGPATH} depends_on: - - membersrvc0 - orderer0 - peer0 @@ -67,6 +59,5 @@ services: - CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer0:7050 - CORE_PEER_MSPCONFIGPATH=${PEER3_CORE_PEER_MSPCFGPATH} depends_on: - - membersrvc0 - orderer0 - peer0 diff --git a/bddtests/docker-compose-next.yml b/bddtests/docker-compose-next.yml index 9745093538f..f341cc8496a 100644 --- a/bddtests/docker-compose-next.yml +++ b/bddtests/docker-compose-next.yml @@ -9,9 +9,4 @@ services: environment: - CORE_NEXT=true - CORE_PEER_ENDORSER_ENABLED=true - - CORE_SECURITY_ENABLED=true - - CORE_PEER_PKI_ECA_PADDR=membersrvc0:7054 - - CORE_PEER_PKI_TCA_PADDR=membersrvc0:7054 - - CORE_PEER_PKI_TLSCA_PADDR=membersrvc0:7054 - - CORE_PEER_PKI_TLS_ROOTCERT_FILE=./bddtests/tlsca.cert diff --git a/bddtests/docker-compose-orderer-base.yml b/bddtests/docker-compose-orderer-base.yml index 0d3b3612f21..66bdf5af59f 100644 --- a/bddtests/docker-compose-orderer-base.yml +++ b/bddtests/docker-compose-orderer-base.yml @@ -7,6 +7,7 @@ services: environment: - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0 - ORDERER_GENERAL_LOGLEVEL=debug + - ORDERER_GENERAL_GENESISMETHOD=${ORDERER_GENERAL_GENESISMETHOD} - ORDERER_GENERAL_GENESISFILE=${ORDERER_GENERAL_GENESISFILE} volumes: - ./volumes/orderer:/var/hyperledger/bddtests/volumes/orderer diff --git a/bddtests/features/bootstrap.feature b/bddtests/features/bootstrap.feature index cb69cf01355..e86726a3024 100644 --- a/bddtests/features/bootstrap.feature +++ b/bddtests/features/bootstrap.feature @@ -13,26 +13,37 @@ Feature: Bootstrap # @doNotDecompose Scenario Outline: Bootstrap a development network with 1 peer and 1 orderer, each having a single independent root of trust (No COP) - #creates 1 self-signed key/cert pair per orderer organization with an associated admin + #creates 1 self-signed key/cert pair per orderer organization Given the orderer network has organizations: | Organization | | ordererOrg0 | + And user requests role of orderer admin by creating a key and csr for orderer and acquires signed certificate from organization: | User | Orderer | Organization | - | orderer0Admin | orderer0 | ordererOrg0 | | orderer0Signer | orderer0 | ordererOrg0 | -# And user requests role of orderer signer by creating a key and csr for orderer and acquires signed certificate from organization: -# | User | Orderer | Organization | And the peer network has organizations: | Organization | | peerOrg0 | + | peerOrg1 | + | peerOrg2 | And a ordererBootstrapAdmin is identified and given access to all public certificates and orderer node info + + And the ordererBootstrapAdmin generates a GUUID to identify the orderer system chain and refer to it by name as "OrdererSystemChainId" + + # Actually creating proto ordere_dot_confoiguration.ChainCreators + And the ordererBootstrapAdmin creates a chain creators policy "chainCreatePolicy1" (network name) for peer orgs who wish to form a network using orderer system chain "OrdererSystemChainId": + | Organization | + | peerOrg0 | + | peerOrg1 | + | peerOrg2 | + + # Order info includes orderer admin/orderer information and address (host:port) from previous steps # Only the peer organizations can vary. - And the ordererBootstrapAdmin creates the genesis block for chain "" for network config policy "" and consensus "" and peer organizations: - | peerOrg0 | + And the ordererBootstrapAdmin creates the genesis block for chain "OrdererSystemChainId" for network config policy "" and consensus "" using chain creators policy "chainCreatePolicy1" + And the orderer admins inspect and approve the genesis block for chain "" @@ -41,7 +52,7 @@ Feature: Bootstrap # We now have an orderer network with NO peers. Now need to configure and start the peer network # This can be currently automated through folder creation of the proper form and placing PEMs. - And user requests role for peer by creating a key and csr for peer and acquires signed certificate from organization: + And user requests role for peer by creating a key and csr for peer and acquires signed certificate from organization: | User | Peer | Organization | | peer0Signer | peer0 | peerOrg0 | | peer1Signer | peer1 | peerOrg0 | @@ -50,6 +61,54 @@ Feature: Bootstrap And we compose "" + # This implicitly incorporates the orderer genesis block info + And the ordererBootstrapAdmin runs the channel template tool to create the orderer configuration template "template1" for application developers using orderer "orderer0" + And the ordererBootstrapAdmin distributes orderer configuration template "template1" and chain creation policy name "chainCreatePolicy1" + + And the following application developers are defined for peer organizations + | Developer | ChainCreationPolicyName | Organization | + | dev0Org0 | chainCreatePolicy1 | peerOrg0 | + + # Need Consortium MSP info and + # need to add the ChannelWriters ConfigItem (using ChannelWriters ref name), + # ChannelReaders ConfigItem (using ChannelReaders ref name)AnchorPeers ConfigItem + # and the ChaincodeLifecyclePolicy Config Item + # NOTE: Template1 will simply hold refs to peer orgs that can create in this channel at the moment + And the user "dev0Org0" creates a peer template "template1" with chaincode deployment policy using chain creation policy name "chainCreatePolicy1" and peer organizations: + | Organization | + | peerOrg0 | + | peerOrg1 | + + # TODO: grab the peer orgs from template1 and put into Murali's MSP info SCIs. + And the user "dev0Org0" creates a signedConfigEnvelope "createChannelSignedConfigEnvelope1" + | ChannelID | Template | Chain Creation Policy Name | + | com.acme.blockchain.jdoe.Channel1 | template1 | chainCreatePolicy1 | + + And the user "dev0Org0" collects signatures for signedConfigEnvelope "createChannelSignedConfigEnvelope1" from peer orgs: + | Organization | + | peerOrg0 | + | peerOrg1 | + + And the user "dev0Org0" creates config Tx "configTx1" using signedConfigEnvelope "createChannelSignedConfigEnvelope1" + + And the user "dev0Org0" broadcasts config Tx "configTx1" to orderer "orderer0" to create channel "com.acme.blockchain.jdoe.Channel1" + + # Sleep as the deliver takes a bit to have the first block ready + And I wait "2" seconds + + When user "dev0Org0" connects to deliver function on orderer "orderer0" + And user "dev0Org0" sends deliver a seek request on orderer "orderer0" with properties: + | ChainId | Start | End | Retries | RetryWaitInSecs | + | com.acme.blockchain.jdoe.Channel1 | 0 | 0 | 3 | 1 | + Then user "dev0Org0" should get a delivery "genesisBlockForMyNewChannel" from "orderer0" of "1" blocks with "1" messages within "1" seconds + + + # This is really a CSCC chaincode invocation. Expect 200 response + And channel admin creates a configTxProposal and asks for endorsement from "peer0" + And channel admin creates a configTxProposal and asks for endorsement from "peer1" + + When channel admin + And peer admins get the genesis block for chain 'chain1' from chainBoostrapAdmin And the peer admins inspect and approve the genesis block for chain 'chain1' diff --git a/bddtests/orderer/configuration_pb2.py b/bddtests/orderer/configuration_pb2.py index 07a0bafe5e4..1fa1a0fb21b 100644 --- a/bddtests/orderer/configuration_pb2.py +++ b/bddtests/orderer/configuration_pb2.py @@ -20,7 +20,7 @@ name='orderer/configuration.proto', package='orderer', syntax='proto3', - serialized_pb=_b('\n\x1borderer/configuration.proto\x12\x07orderer\x1a\x13\x63ommon/common.proto\"\x1d\n\rConsensusType\x12\x0c\n\x04type\x18\x01 \x01(\t\"$\n\tBatchSize\x12\x17\n\x0fmaxMessageCount\x18\x01 \x01(\r\"\x1f\n\x0c\x42\x61tchTimeout\x12\x0f\n\x07timeout\x18\x01 \x01(\t\"0\n\x0e\x43reationPolicy\x12\x0e\n\x06policy\x18\x01 \x01(\t\x12\x0e\n\x06\x64igest\x18\x02 \x01(\x0c\"\x1d\n\rIngressPolicy\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1c\n\x0c\x45gressPolicy\x12\x0c\n\x04name\x18\x01 \x01(\t\"!\n\rChainCreators\x12\x10\n\x08policies\x18\x01 \x03(\t\"\x1f\n\x0cKafkaBrokers\x12\x0f\n\x07\x62rokers\x18\x01 \x03(\tB.Z,github.com/hyperledger/fabric/protos/ordererb\x06proto3') + serialized_pb=_b('\n\x1borderer/configuration.proto\x12\x07orderer\x1a\x13\x63ommon/common.proto\"\x1d\n\rConsensusType\x12\x0c\n\x04type\x18\x01 \x01(\t\">\n\tBatchSize\x12\x17\n\x0fmaxMessageCount\x18\x01 \x01(\r\x12\x18\n\x10\x61\x62soluteMaxBytes\x18\x02 \x01(\r\"\x1f\n\x0c\x42\x61tchTimeout\x12\x0f\n\x07timeout\x18\x01 \x01(\t\"0\n\x0e\x43reationPolicy\x12\x0e\n\x06policy\x18\x01 \x01(\t\x12\x0e\n\x06\x64igest\x18\x02 \x01(\x0c\"\x1d\n\rIngressPolicy\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1c\n\x0c\x45gressPolicy\x12\x0c\n\x04name\x18\x01 \x01(\t\"!\n\rChainCreators\x12\x10\n\x08policies\x18\x01 \x03(\t\"\x1f\n\x0cKafkaBrokers\x12\x0f\n\x07\x62rokers\x18\x01 \x03(\tB.Z,github.com/hyperledger/fabric/protos/ordererb\x06proto3') , dependencies=[common_dot_common__pb2.DESCRIPTOR,]) _sym_db.RegisterFileDescriptor(DESCRIPTOR) @@ -73,6 +73,13 @@ message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), + _descriptor.FieldDescriptor( + name='absoluteMaxBytes', full_name='orderer.BatchSize.absoluteMaxBytes', index=1, + number=2, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), ], extensions=[ ], @@ -86,7 +93,7 @@ oneofs=[ ], serialized_start=92, - serialized_end=128, + serialized_end=154, ) @@ -116,8 +123,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=130, - serialized_end=161, + serialized_start=156, + serialized_end=187, ) @@ -154,8 +161,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=163, - serialized_end=211, + serialized_start=189, + serialized_end=237, ) @@ -185,8 +192,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=213, - serialized_end=242, + serialized_start=239, + serialized_end=268, ) @@ -216,8 +223,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=244, - serialized_end=272, + serialized_start=270, + serialized_end=298, ) @@ -247,8 +254,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=274, - serialized_end=307, + serialized_start=300, + serialized_end=333, ) @@ -278,8 +285,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=309, - serialized_end=340, + serialized_start=335, + serialized_end=366, ) DESCRIPTOR.message_types_by_name['ConsensusType'] = _CONSENSUSTYPE diff --git a/bddtests/steps/bootstrap_impl.py b/bddtests/steps/bootstrap_impl.py index 57fc013ddf7..5ac078517c0 100644 --- a/bddtests/steps/bootstrap_impl.py +++ b/bddtests/steps/bootstrap_impl.py @@ -16,6 +16,17 @@ import bdd_test_util import bootstrap_util +import orderer_util +import time + +class ChannelCreationInfo: + 'Used to store the information needed to construct Config TX for orderer broadcast to create a new channel' + def __init__(self, channelId, channelCreationPolicyName, signedConfigEnvelope): + self.channelId = channelId + self.channelCreationPolicyName = channelCreationPolicyName + self.signedConfigEnvelope = signedConfigEnvelope + + @given(u'the orderer network has organizations') def step_impl(context): @@ -52,10 +63,17 @@ def step_impl(context): def step_impl(context): directory = bootstrap_util.getDirectory(context) assert len(directory.ordererAdminTuples) > 0, "No orderer admin tuples defined!!!" + # Simply create the user + bootstrap_util.getOrdererBootstrapAdmin(context, shouldCreate=True) + +@given(u'the ordererBootstrapAdmin creates the genesis block for chain "{ordererSystemChainId}" for network config policy "{networkConfigPolicy}" and consensus "{consensusType}" using chain creators policy "{chainCreatorPolicyNames}"') +def step_impl(context, ordererSystemChainId, networkConfigPolicy, consensusType, chainCreatorPolicyNames): + ordererBootstrapAdmin = bootstrap_util.getOrdererBootstrapAdmin(context) + # Retrieve the chainCreators config items required for now (tuple). + chainCreatorsSignedConfigItems = ordererBootstrapAdmin.tags[chainCreatorPolicyNames] + ordererSystemChainIdGUUID = ordererBootstrapAdmin.tags[ordererSystemChainId] -@given(u'the ordererBootstrapAdmin creates the genesis block for chain "{ordererSystemChainId}" for network config policy "{networkConfigPolicy}" and consensus "{consensusType}" and peer organizations') -def step_impl(context, ordererSystemChainId, networkConfigPolicy, consensusType): - genesisBlock = bootstrap_util.createGenesisBlock(context, ordererSystemChainId, networkConfigPolicy, consensusType) + (genesisBlock,envelope) = bootstrap_util.createGenesisBlock(context, ordererSystemChainIdGUUID, consensusType, signedConfigItems=list(chainCreatorsSignedConfigItems)) bootstrap_util.OrdererGensisBlockCompositionCallback(context, genesisBlock) bootstrap_util.PeerCompositionCallback(context) @@ -66,4 +84,129 @@ def step_impl(context, chainId): @given(u'the orderer admins use the genesis block for chain "{chainId}" to configure orderers') def step_impl(context, chainId): pass - #raise NotImplementedError(u'STEP: Given the orderer admins use the genesis block for chain "**TEST_CHAINID**" to configure orderers') \ No newline at end of file + #raise NotImplementedError(u'STEP: Given the orderer admins use the genesis block for chain "**TEST_CHAINID**" to configure orderers') + +@given(u'the ordererBootstrapAdmin generates a GUUID to identify the orderer system chain and refer to it by name as "{ordererSystemChainId}"') +def step_impl(context, ordererSystemChainId): + directory = bootstrap_util.getDirectory(context) + ordererBootstrapAdmin = bootstrap_util.getOrdererBootstrapAdmin(context) + ordererBootstrapAdmin.tags[ordererSystemChainId] = bootstrap_util.GetUUID() + + +@given(u'the ordererBootstrapAdmin creates a chain creators policy "{chainCreatePolicyName}" (network name) for peer orgs who wish to form a network using orderer system chain "{ordererSystemChainId}"') +def step_impl(context, chainCreatePolicyName, ordererSystemChainId): + directory = bootstrap_util.getDirectory(context) + ordererBootstrapAdmin = bootstrap_util.getOrdererBootstrapAdmin(context) + ordererSystemChainIdGuuid = ordererBootstrapAdmin.tags[ordererSystemChainId] + + # Collect the orgs from the table + orgNames = [row['Organization'] for row in context.table.rows] + + (chainCreationPolicyNamesSignedConfigItem, chainCreatorsOrgsPolicySignedConfigItem) = \ + bootstrap_util.createChainCreatorsPolicy(context=context, chainCreatePolicyName=chainCreatePolicyName, chaindId=ordererSystemChainIdGuuid, orgNames=orgNames) + + ordererBootstrapAdmin.tags[chainCreatePolicyName] = (chainCreationPolicyNamesSignedConfigItem, chainCreatorsOrgsPolicySignedConfigItem) + + +@given(u'the ordererBootstrapAdmin runs the channel template tool to create the orderer configuration template "{templateName}" for application developers using orderer "{ordererComposeService}"') +def step_impl(context, templateName, ordererComposeService): + pass + + +@given(u'the ordererBootstrapAdmin distributes orderer configuration template "template1" and chain creation policy name "chainCreatePolicy1"') +def step_impl(context): + pass + + +@given(u'the user "{userName}" creates a peer template "{templateName}" with chaincode deployment policy using chain creation policy name "{chainCreatePolicyName}" and peer organizations') +def step_impl(context, userName, templateName, chainCreatePolicyName): + directory = bootstrap_util.getDirectory(context) + user = directory.getUser(userName) + pass + +@given(u'the user "{userName}" creates a signedConfigEnvelope "{createChannelSignedConfigEnvelope}"') +def step_impl(context, userName, createChannelSignedConfigEnvelope): + directory = bootstrap_util.getDirectory(context) + user = directory.getUser(userName) + ordererBootstrapAdmin = bootstrap_util.getOrdererBootstrapAdmin(context) + + muralisRequiredSignedConfigItems = [] + + channelID = context.table.rows[0]["ChannelID"] + chainCreationPolicyName = context.table.rows[0]["Chain Creation Policy Name"] + + # Intermediate step until template tool is ready + signedConfigItems = bootstrap_util.createSignedConfigItems(context, channelID, "solo", signedConfigItems=muralisRequiredSignedConfigItems) + + #NOTE: Conidered passing signing key for appDeveloper, but decided that the peer org signatures they need to collect subsequently should be proper way + signedConfigEnvelope = bootstrap_util.signInitialChainConfig(signedConfigItems=signedConfigItems, chainId=channelID, chainCreationPolicyName=chainCreationPolicyName) + + user.tags[createChannelSignedConfigEnvelope] = ChannelCreationInfo(channelID, chainCreationPolicyName, signedConfigEnvelope) + + # Construct TX Config Envelope, broadcast, expect success, and then connect to deliver to revtrieve block. + # Make sure the blockdata exactly the TxConfigEnvelope I submitted. + # txConfigEnvelope = bootstrap_util.createConfigTxEnvelope(chainId=channelID, signedConfigEnvelope=signedConfigEnvelope) + + +@given(u'the following application developers are defined for peer organizations') +def step_impl(context): + assert 'table' in context, "Expected table with triplet of Developer/ChainCreationPolicyName/Organization" + directory = bootstrap_util.getDirectory(context) + for row in context.table.rows: + directory.registerOrdererAdminTuple(row['Developer'], row['ChainCreationPolicyName'], row['Organization']) + +@given(u'the user "{userName}" collects signatures for signedConfigEnvelope "{createChannelSignedConfigEnvelopeName}" from peer orgs') +def step_impl(context, userName, createChannelSignedConfigEnvelopeName): + assert 'table' in context, "Expected table of peer organizations" + directory = bootstrap_util.getDirectory(context) + user = directory.getUser(userName=userName) + # Get the ChannelCreationInfo object that holds the signedConfigEnvelope + channelCreationInfo = user.tags[createChannelSignedConfigEnvelopeName] + signedConfigEnvelope = channelCreationInfo.signedConfigEnvelope + for row in context.table.rows: + org = directory.getOrganization(row['Organization']) + assert bootstrap_util.Network.Peer in org.networks, "Organization '{0}' not in Peer network".format(org.name) + bootstrap_util.BootstrapHelper.addSignatureToSignedConfigItem(signedConfigEnvelope.Items[0], (org.ecdsaSigningKey, org.getSelfSignedCert())) + print("Signatures for signedConfigEnvelope:\n {0}\n".format(signedConfigEnvelope.Items[0])) + +@given(u'the user "{userName}" creates config Tx "{configTxName}" using signedConfigEnvelope "{createChannelSignedConfigEnvelopeName}"') +def step_impl(context, userName, configTxName, createChannelSignedConfigEnvelopeName): + directory = bootstrap_util.getDirectory(context) + user = directory.getUser(userName=userName) + channelCreationInfo = user.tags[createChannelSignedConfigEnvelopeName] + user.tags[configTxName] = bootstrap_util.createConfigTxEnvelope(channelCreationInfo.channelId, channelCreationInfo.signedConfigEnvelope) + +@given(u'the user "{userName}" broadcasts config Tx "{configTxName}" to orderer "{orderer}" to create channel "{channelId}"') +def step_impl(context, userName, configTxName, orderer, channelId): + directory = bootstrap_util.getDirectory(context) + user = directory.getUser(userName=userName) + configTxEnvelope = user.tags[configTxName] + bootstrap_util.broadcastCreateChannelConfigTx(context=context, composeService=orderer, chainId=channelId, user=user, configTxEnvelope=configTxEnvelope) + +@when(u'user "{userName}" connects to deliver function on orderer "{composeService}"') +def step_impl(context, userName, composeService): + directory = bootstrap_util.getDirectory(context) + user = directory.getUser(userName=userName) + user.connectToDeliverFunction(context, composeService) + +@when(u'user "{userName}" sends deliver a seek request on orderer "{composeService}" with properties') +def step_impl(context, userName, composeService): + directory = bootstrap_util.getDirectory(context) + user = directory.getUser(userName=userName) + row = context.table.rows[0] + chainID = row['ChainId'] + start, end, = orderer_util.convertSeek(row['Start']), orderer_util.convertSeek(row['End']) + + streamHelper = user.getDelivererStreamHelper(context, composeService) + streamHelper.seekToRange(chainID=chainID, start = start, end = end) + +@then(u'user "{userName}" should get a delivery "{deliveryName}" from "{composeService}" of "{expectedBlocks}" blocks with "{numMsgsToBroadcast}" messages within "{batchTimeout}" seconds') +def step_impl(context, userName, deliveryName, composeService, expectedBlocks, numMsgsToBroadcast, batchTimeout): + directory = bootstrap_util.getDirectory(context) + user = directory.getUser(userName=userName) + streamHelper = user.getDelivererStreamHelper(context, composeService) + + blocks = streamHelper.getBlocks() + + # Verify block count + assert len(blocks) == int(expectedBlocks), "Expected {0} blocks, received {1}".format(expectedBlocks, len(blocks)) diff --git a/bddtests/steps/bootstrap_util.py b/bddtests/steps/bootstrap_util.py index 44ca19584d4..30ae2980d71 100644 --- a/bddtests/steps/bootstrap_util.py +++ b/bddtests/steps/bootstrap_util.py @@ -21,35 +21,53 @@ from OpenSSL import crypto from OpenSSL import rand +from ecdsa import SigningKey, NIST384p, NIST256p + from collections import namedtuple from enum import Enum from google.protobuf import timestamp_pb2 from common import common_pb2 as common_dot_common_pb2 from common import configuration_pb2 as common_dot_configuration_pb2 +from common import msp_principal_pb2 + # import orderer from orderer import configuration_pb2 as orderer_dot_configuration_pb2 +import orderer_util import os import shutil import compose +import uuid # Type to represent tuple of user, nodeName, ogranization NodeAdminTuple = namedtuple("NodeAdminTuple", ['user', 'nodeName', 'organization']) +def GetUUID(): + return compose.Composition.GetUUID() + -def createKey(): +def createRSAKey(): #Create RSA key, 2048 bit pk = crypto.PKey() pk.generate_key(crypto.TYPE_RSA,2048) assert pk.check()==True return pk +def createECDSAKey(curve=NIST384p): + #Create ECDSA key + # sk = SigningKey.generate(curve=NIST384p) + sk = SigningKey.generate(curve=NIST256p) + return sk + + def computeCryptoHash(data): - s = hashlib.sha3_256() + ' This will currently return 128 hex characters' + # s = hashlib.sha3_256() + s = hashlib.shake_256() s.update(data) - return s.hexdigest() + return s.digest(64) def createCertRequest(pkey, digest="sha256", **name): @@ -110,18 +128,24 @@ class Entity: def __init__(self, name): self.name = name - self.pKey = createKey() + #Create a ECDSA key, then a crypto pKey from the DER for usage with cert requests, etc. + self.ecdsaSigningKey = createECDSAKey() + self.pKey = crypto.load_privatekey(crypto.FILETYPE_ASN1, self.ecdsaSigningKey.to_der()) def createCertRequest(self, nodeName): req = createCertRequest(self.pKey, CN=nodeName) print("request => {0}".format(crypto.dump_certificate_request(crypto.FILETYPE_PEM, req))) return req + def sign(self, dataAsBytearray): + return self.ecdsaSigningKey.sign(dataAsBytearray) -class User(Entity): +class User(Entity, orderer_util.UserRegistration): def __init__(self, name): Entity.__init__(self, name) + orderer_util.UserRegistration.__init__(self, name) + self.tags = {} class Network(Enum): Orderer = 1 @@ -231,22 +255,38 @@ class BootstrapHelper: KEY_INGRESS_POLICY = "IngressPolicy" KEY_EGRESS_POLICY = "EgressPolicy" KEY_BATCH_SIZE = "BatchSize" + KEY_CREATIONPOLICY = "CreationPolicy" DEFAULT_MODIFICATION_POLICY_ID = "DefaultModificationPolicy" DEFAULT_CHAIN_CREATORS = [KEY_ACCEPT_ALL_POLICY] DEFAULT_NONCE_SIZE = 24 - def __init__(self, chainId = "TestChain", lastModified = 0, msgVersion = 1, epoch = 0, consensusType = "solo", batchSize = 10): + def __init__(self, chainId = "TestChain", lastModified = 0, msgVersion = 1, epoch = 0, consensusType = "solo", batchSize = 10, absoluteMaxBytes=100000000, signers=[]): self.chainId = str(chainId) self.lastModified = lastModified self.msgVersion = msgVersion self.epoch = epoch self.consensusType = consensusType self.batchSize = batchSize + self.absoluteMaxBytes = absoluteMaxBytes + self.signers = signers + + @classmethod + def getNonce(cls): + return rand.bytes(BootstrapHelper.DEFAULT_NONCE_SIZE) + + @classmethod + def addSignatureToSignedConfigItem(cls, signedConfigItem, (signingKey, cert)): + sigHeader = common_dot_common_pb2.SignatureHeader(creator=crypto.dump_certificate(crypto.FILETYPE_ASN1,cert),nonce=BootstrapHelper.getNonce()) + sigHeaderBytes = sigHeader.SerializeToString() + # Signature over the concatenation of configurationItem bytes and signatureHeader bytes + signature = signingKey.sign(signedConfigItem.ConfigurationItem + sigHeaderBytes) + # Now add new signature to Signatures repeated field + newConfigSig = signedConfigItem.Signatures.add() + newConfigSig.signatureHeader=sigHeaderBytes + newConfigSig.signature=signature - def getNonce(self): - return rand.bytes(self.DEFAULT_NONCE_SIZE) def makeChainHeader(self, type = common_dot_common_pb2.HeaderType.Value("CONFIGURATION_ITEM"), version = 1, timestamp = timestamp_pb2.Timestamp(seconds = int(time.time()), nanos = 0)): @@ -280,7 +320,7 @@ def encodeBatchSize(self): configItem = self.getConfigItem( commonConfigType=common_dot_configuration_pb2.ConfigurationItem.ConfigurationType.Value("Orderer"), key=BootstrapHelper.KEY_BATCH_SIZE, - value=orderer_dot_configuration_pb2.BatchSize(maxMessageCount=self.batchSize).SerializeToString()) + value=orderer_dot_configuration_pb2.BatchSize(maxMessageCount=self.batchSize, absoluteMaxBytes=self.absoluteMaxBytes).SerializeToString()) return self.signConfigItem(configItem) def encodeConsensusType(self): @@ -290,13 +330,21 @@ def encodeConsensusType(self): value=orderer_dot_configuration_pb2.ConsensusType(type=self.consensusType).SerializeToString()) return self.signConfigItem(configItem) - def encodeChainCreators(self): + def encodeChainCreators(self, ciValue = orderer_dot_configuration_pb2.ChainCreators(policies=DEFAULT_CHAIN_CREATORS).SerializeToString()): configItem = self.getConfigItem( commonConfigType=common_dot_configuration_pb2.ConfigurationItem.ConfigurationType.Value("Orderer"), key=BootstrapHelper.KEY_CHAIN_CREATORS, - value=orderer_dot_configuration_pb2.ChainCreators(policies=BootstrapHelper.DEFAULT_CHAIN_CREATORS).SerializeToString()) + value=ciValue) return self.signConfigItem(configItem) + def encodePolicy(self, key, policy=common_dot_configuration_pb2.Policy(type=1, policy=AuthDSLHelper.Envelope(signaturePolicy=AuthDSLHelper.NOutOf(0,[]), identities=[]).SerializeToString())): + configItem = self.getConfigItem( + commonConfigType=common_dot_configuration_pb2.ConfigurationItem.ConfigurationType.Value("Policy"), + key=key, + value=policy.SerializeToString()) + return self.signConfigItem(configItem) + + def encodeEgressPolicy(self): configItem = self.getConfigItem( commonConfigType=common_dot_configuration_pb2.ConfigurationItem.ConfigurationType.Value("Orderer"), @@ -315,43 +363,71 @@ def encodeAcceptAllPolicy(self): configItem = self.getConfigItem( commonConfigType=common_dot_configuration_pb2.ConfigurationItem.ConfigurationType.Value("Policy"), key=BootstrapHelper.KEY_ACCEPT_ALL_POLICY, - value=AuthDSLHelper.Envelope(signaturePolicy=AuthDSLHelper.NOutOf(0,[]), identities=[]).SerializeToString()) + value=common_dot_configuration_pb2.Policy(type=1, policy=AuthDSLHelper.Envelope(signaturePolicy=AuthDSLHelper.NOutOf(0,[]), identities=[]).SerializeToString()).SerializeToString()) return self.signConfigItem(configItem) def lockDefaultModificationPolicy(self): configItem = self.getConfigItem( commonConfigType=common_dot_configuration_pb2.ConfigurationItem.ConfigurationType.Value("Policy"), key=BootstrapHelper.DEFAULT_MODIFICATION_POLICY_ID, - value=AuthDSLHelper.Envelope(signaturePolicy=AuthDSLHelper.NOutOf(1,[]), identities=[]).SerializeToString()) + value=common_dot_configuration_pb2.Policy(type=1, policy=AuthDSLHelper.Envelope(signaturePolicy=AuthDSLHelper.NOutOf(1,[]), identities=[]).SerializeToString()).SerializeToString()) return self.signConfigItem(configItem) def computeBlockDataHash(self, blockData): return computeCryptoHash(blockData.SerializeToString()) -# Registerses a user on a specific composeService + + def signInitialChainConfig(self, signedConfigItems, chainCreationPolicyName): + 'Create a signedConfigItem using previous config items' + # Create byte array to store concatenated bytes + # concatenatedConfigItemsBytes = bytearray() + # for sci in signedConfigItems: + # concatenatedConfigItemsBytes = concatenatedConfigItemsBytes + bytearray(sci.ConfigurationItem) + # hash = computeCryptoHash(concatenatedConfigItemsBytes) + data = '' + for sci in signedConfigItems: + data = data + sci.ConfigurationItem + # Compute hash over concatenated bytes + hash = computeCryptoHash(data) + configItem = self.getConfigItem( + commonConfigType=common_dot_configuration_pb2.ConfigurationItem.ConfigurationType.Value("Orderer"), + key=BootstrapHelper.KEY_CREATIONPOLICY, + value=orderer_dot_configuration_pb2.CreationPolicy(policy=chainCreationPolicyName, digest=hash).SerializeToString()) + return [self.signConfigItem(configItem)] + signedConfigItems + + +def signInitialChainConfig(signedConfigItems, chainId, chainCreationPolicyName): + bootstrapHelper = BootstrapHelper(chainId = chainId) + # Returns a list prepended with a signedConfiguration + signedConfigItems = bootstrapHelper.signInitialChainConfig(signedConfigItems, chainCreationPolicyName) + return common_dot_configuration_pb2.ConfigurationEnvelope(Items=signedConfigItems) + def getDirectory(context): if 'bootstrapDirectory' not in context: context.bootstrapDirectory = Directory() return context.bootstrapDirectory - -def createGenesisBlock(context, chainId, networkConfigPolicy, consensusType): - 'Generates the genesis block for starting the oderers and for use in the chain config transaction by peers' - #assert not "bootstrapGenesisBlock" in context,"Genesis block already created:\n{0}".format(context.bootstrapGenesisBlock) +def getOrdererBootstrapAdmin(context, shouldCreate=False): directory = getDirectory(context) - assert len(directory.ordererAdminTuples) > 0, "No orderer admin tuples defined!!!" + ordererBootstrapAdmin = directory.getUser(userName="ordererBootstrapAdmin", shouldCreate=shouldCreate) + return ordererBootstrapAdmin +def createSignedConfigItems(context, chainId, consensusType, signedConfigItems = []): + # directory = getDirectory(context) + # assert len(directory.ordererAdminTuples) > 0, "No orderer admin tuples defined!!!" bootstrapHelper = BootstrapHelper(chainId = chainId, consensusType=consensusType) - configItems = [] + configItems = signedConfigItems configItems.append(bootstrapHelper.encodeBatchSize()) configItems.append(bootstrapHelper.encodeConsensusType()) - configItems.append(bootstrapHelper.encodeChainCreators()) configItems.append(bootstrapHelper.encodeAcceptAllPolicy()) configItems.append(bootstrapHelper.encodeIngressPolicy()) + configItems.append(bootstrapHelper.encodeEgressPolicy()) configItems.append(bootstrapHelper.lockDefaultModificationPolicy()) - configEnvelope = common_dot_configuration_pb2.ConfigurationEnvelope(Items=configItems) + return configItems +def createConfigTxEnvelope(chainId, signedConfigEnvelope): + bootstrapHelper = BootstrapHelper(chainId = chainId) payloadChainHeader = bootstrapHelper.makeChainHeader(type=common_dot_common_pb2.HeaderType.Value("CONFIGURATION_TRANSACTION")) #Now the SignatureHeader @@ -366,8 +442,46 @@ def createGenesisBlock(context, chainId, networkConfigPolicy, consensusType): chainHeader=payloadChainHeader, signatureHeader=payloadSignatureHeader, ) - payload = common_dot_common_pb2.Payload(header=payloadHeader, data=configEnvelope.SerializeToString()) + payload = common_dot_common_pb2.Payload(header=payloadHeader, data=signedConfigEnvelope.SerializeToString()) envelope = common_dot_common_pb2.Envelope(payload=payload.SerializeToString(), signature=None) + return envelope + +def createGenesisBlock(context, chainId, consensusType, signedConfigItems = []): + 'Generates the genesis block for starting the oderers and for use in the chain config transaction by peers' + #assert not "bootstrapGenesisBlock" in context,"Genesis block already created:\n{0}".format(context.bootstrapGenesisBlock) + directory = getDirectory(context) + assert len(directory.ordererAdminTuples) > 0, "No orderer admin tuples defined!!!" + + configItems = createSignedConfigItems(context, chainId, consensusType, signedConfigItems = signedConfigItems) + + bootstrapHelper = BootstrapHelper(chainId = chainId, consensusType=consensusType) + # configItems = signedConfigItems + # configItems.append(bootstrapHelper.encodeBatchSize()) + # configItems.append(bootstrapHelper.encodeConsensusType()) + # configItems.append(bootstrapHelper.encodeAcceptAllPolicy()) + # configItems.append(bootstrapHelper.encodeIngressPolicy()) + # configItems.append(bootstrapHelper.encodeEgressPolicy()) + # configItems.append(bootstrapHelper.lockDefaultModificationPolicy()) + configEnvelope = common_dot_configuration_pb2.ConfigurationEnvelope(Items=configItems) + + + # payloadChainHeader = bootstrapHelper.makeChainHeader(type=common_dot_common_pb2.HeaderType.Value("CONFIGURATION_TRANSACTION")) + # + # #Now the SignatureHeader + # serializedCreatorCertChain = None + # nonce = None + # payloadSignatureHeader = common_dot_common_pb2.SignatureHeader( + # creator=serializedCreatorCertChain, + # nonce=bootstrapHelper.getNonce(), + # ) + # + # payloadHeader = common_dot_common_pb2.Header( + # chainHeader=payloadChainHeader, + # signatureHeader=payloadSignatureHeader, + # ) + # payload = common_dot_common_pb2.Payload(header=payloadHeader, data=configEnvelope.SerializeToString()) + # envelope = common_dot_common_pb2.Envelope(payload=payload.SerializeToString(), signature=None) + envelope = createConfigTxEnvelope(chainId, configEnvelope) blockData = common_dot_common_pb2.BlockData(Data=[envelope.SerializeToString()]) @@ -379,7 +493,7 @@ def createGenesisBlock(context, chainId, networkConfigPolicy, consensusType): DataHash=bootstrapHelper.computeBlockDataHash(blockData), ), Data=blockData, - Metadata=None, + Metadata=common_dot_common_pb2.BlockMetadata(Metadata=("",common_dot_common_pb2.Metadata(value=common_dot_common_pb2.LastConfiguration(index=0).SerializeToString()).SerializeToString(),"")), ) # Add this back once crypto certs are required @@ -389,7 +503,7 @@ def createGenesisBlock(context, chainId, networkConfigPolicy, consensusType): # print("UserCert for orderer genesis:\n{0}\n".format(certAsPEM)) # print("") - return block + return (block, envelope) class PathType(Enum): 'Denotes whether Path relative to Local filesystem or Containers volume reference.' @@ -428,6 +542,7 @@ def decomposing(self, composition, context): shutil.rmtree(self.getVolumePath(composition)) def getEnv(self, composition, context, env): + env["ORDERER_GENERAL_GENESISMETHOD"]="file" env["ORDERER_GENERAL_GENESISFILE"]=self.getGenesisFilePath(composition, pathType=PathType.Container) @@ -480,7 +595,8 @@ def composing(self, composition, context): # Put the associated private key into the keystore folder user = directory.getUser(pnt.user, shouldCreate=False) with open("{0}/keystore/{1}.pem".format(localMspConfigPath, pnt.user), "w") as f: - f.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, user.pKey)) + f.write(user.ecdsaSigningKey.to_pem()) + # f.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, user.pKey)) def decomposing(self, composition, context): @@ -492,5 +608,32 @@ def getEnv(self, composition, context, env): localMspConfigPath = self.getLocalMspConfigPath(composition, peerService, pathType=PathType.Container) env["{0}_CORE_PEER_MSPCFGPATH".format(peerService.upper())]=localMspConfigPath +def createChainCreatorsPolicy(context, chainCreatePolicyName, chaindId, orgNames): + 'Creates the chain Creator Policy with name' + directory = getDirectory(context) + bootstrapHelper = BootstrapHelper(chainId = chaindId) + chainCreationPolicyNamesSignedConfigItem = bootstrapHelper.encodeChainCreators(ciValue = orderer_dot_configuration_pb2.ChainCreators(policies=[chainCreatePolicyName]).SerializeToString()) + + + + # This represents the domain of organization which can create channels for the orderer + # First create org MSPPrincicpal + + # Collect the orgs from the table + mspPrincipalList = [] + for org in [directory.getOrganization(orgName) for orgName in orgNames]: + mspPrincipalList.append(msp_principal_pb2.MSPPrincipal(PrincipalClassification=msp_principal_pb2.MSPPrincipal.Classification.Value("ByIdentity"), + Principal=crypto.dump_certificate(crypto.FILETYPE_ASN1, org.getSelfSignedCert())).SerializeToString()) + + chainCreatorsOrgsPolicySignedConfigItem = bootstrapHelper.encodePolicy(key=chainCreatePolicyName , policy=common_dot_configuration_pb2.Policy(type=1, policy=AuthDSLHelper.Envelope(signaturePolicy=AuthDSLHelper.NOutOf(0,[]), identities=mspPrincipalList).SerializeToString())) + print("signed Config Item:\n{0}\n".format(chainCreationPolicyNamesSignedConfigItem)) + print("chain Creation orgs signed Config Item:\n{0}\n".format(chainCreatorsOrgsPolicySignedConfigItem)) + return (chainCreationPolicyNamesSignedConfigItem, chainCreatorsOrgsPolicySignedConfigItem) + def setOrdererBootstrapGenesisBlock(genesisBlock): 'Responsible for setting the GensisBlock for the Orderer nodes upon composition' + +def broadcastCreateChannelConfigTx(context, composeService, chainId, configTxEnvelope, user): + + dataFunc = lambda x: configTxEnvelope + user.broadcastMessages(context=context,numMsgsToBroadcast=1,composeService=composeService, chainID=chainId ,dataFunc=dataFunc, chainHeaderType=common_dot_common_pb2.CONFIGURATION_TRANSACTION) diff --git a/bddtests/steps/compose.py b/bddtests/steps/compose.py index a8ae55b5313..66279eff4bf 100644 --- a/bddtests/steps/compose.py +++ b/bddtests/steps/compose.py @@ -41,6 +41,9 @@ def decomposing(self, composition, context): def getEnv(self, composition, context, env): pass +def GetDockerSafeUUID(): + return str(uuid.uuid1()).replace('-','') + class Composition: @classmethod @@ -56,10 +59,11 @@ def GetCompositionCallbacksFromContext(cls, context): return context.compositionCallbacks - def GetUUID(): - return str(uuid.uuid1()).replace('-','') + @classmethod + def GetUUID(cls): + return GetDockerSafeUUID() - def __init__(self, context, composeFilesYaml, projectName = GetUUID()): + def __init__(self, context, composeFilesYaml, projectName = GetDockerSafeUUID()): self.projectName = projectName self.context = context self.containerDataList = [] diff --git a/bddtests/steps/orderer_impl.py b/bddtests/steps/orderer_impl.py index 4765095cbe9..9630d1d36d2 100644 --- a/bddtests/steps/orderer_impl.py +++ b/bddtests/steps/orderer_impl.py @@ -65,16 +65,10 @@ def step_impl(context, enrollId, expectedBlocks, numMsgsToBroadcast, batchTimeou assert len(blocks) == int(expectedBlocks), "Expected {0} blocks, received {1}".format(expectedBlocks, len(blocks)) -def convertSeek(utfString): - try: - return int(utfString) - except ValueError: - return str(utfString) - @when(u'user "{enrollId}" sends deliver a seek request on "{composeService}" with properties') def step_impl(context, enrollId, composeService): row = context.table.rows[0] - start, end, = convertSeek(row['Start']), convertSeek(row['End']) + start, end, = orderer_util.convertSeek(row['Start']), orderer_util.convertSeek(row['End']) userRegistration = orderer_util.getUserRegistration(context, enrollId) streamHelper = userRegistration.getDelivererStreamHelper(context, composeService) diff --git a/bddtests/steps/orderer_util.py b/bddtests/steps/orderer_util.py index d09100b6cea..d677cbdac9f 100644 --- a/bddtests/steps/orderer_util.py +++ b/bddtests/steps/orderer_util.py @@ -38,6 +38,23 @@ # The default chain ID when the system is statically bootstrapped for testing TEST_CHAIN_ID = "**TEST_CHAINID**" +def _defaultDataFunction(index): + payload = common_pb2.Payload( + header = common_pb2.Header( + chainHeader = common_pb2.ChainHeader( + chainID = TEST_CHAIN_ID, + type = common_pb2.ENDORSER_TRANSACTION, + ), + signatureHeader = common_pb2.SignatureHeader(), + ), + data = str("BDD test: {0}".format(datetime.datetime.utcnow())), + ) + envelope = common_pb2.Envelope( + payload = payload.SerializeToString() + ) + return envelope + + class StreamHelper: def __init__(self): @@ -99,7 +116,7 @@ def __init__(self, ordererStub, timeout = 1): self.replyGenerator = ordererStub.Deliver(sendGenerator, timeout + 1) def seekToRange(self, chainID = TEST_CHAIN_ID, start = 'Oldest', end = 'Newest'): - self.sendQueue.put(createSeekInfo(start = start)) + self.sendQueue.put(createSeekInfo(start = start, chainID = chainID)) def getBlocks(self): blocks = [] @@ -121,10 +138,8 @@ def getBlocks(self): class UserRegistration: - def __init__(self, secretMsg, composeService): - self.enrollId = secretMsg['enrollId'] - self.secretMsg = secretMsg - self.composeService = composeService + def __init__(self, userName): + self.userName= userName self.tags = {} # Dictionary of composeService->atomic broadcast grpc Stub self.atomicBroadcastStubsDict = {} @@ -132,10 +147,10 @@ def __init__(self, secretMsg, composeService): self.abDeliversStreamHelperDict = {} def getUserName(self): - return self.secretMsg['enrollId'] + return self.userName - def connectToDeliverFunction(self, context, composeService): + def connectToDeliverFunction(self, context, composeService, timeout=1): 'Connect to the deliver function and drain messages to associated orderer queue' assert not composeService in self.abDeliversStreamHelperDict, "Already connected to deliver stream on {0}".format(composeService) streamHelper = DeliverStreamHelper(self.getABStubForComposeService(context, composeService)) @@ -149,14 +164,14 @@ def getDelivererStreamHelper(self, context, composeService): - def broadcastMessages(self, context, numMsgsToBroadcast, composeService): + def broadcastMessages(self, context, numMsgsToBroadcast, composeService, chainID=TEST_CHAIN_ID, dataFunc=_defaultDataFunction, chainHeaderType=common_pb2.ENDORSER_TRANSACTION): abStub = self.getABStubForComposeService(context, composeService) - replyGenerator = abStub.Broadcast(generateBroadcastMessages(numToGenerate = int(numMsgsToBroadcast)), 2) + replyGenerator = abStub.Broadcast(generateBroadcastMessages(chainID=chainID, numToGenerate = int(numMsgsToBroadcast), dataFunc=dataFunc, chainHeaderType=chainHeaderType), 2) counter = 0 try: for reply in replyGenerator: counter += 1 - print("{0} received reply: {1}, counter = {2}".format(self.enrollId, reply, counter)) + print("{0} received reply: {1}, counter = {2}".format(self.getUserName(), reply, counter)) if counter == int(numMsgsToBroadcast): break except Exception as e: @@ -184,7 +199,7 @@ def registerUser(context, secretMsg, composeService): context.ordererUsers = {} if userName in context.ordererUsers: raise Exception("Orderer user already registered: {0}".format(userName)) - userRegistration = UserRegistration(secretMsg, composeService) + userRegistration = UserRegistration(secretMsg) context.ordererUsers[userName] = userRegistration return userRegistration @@ -208,6 +223,12 @@ def seekPosition(position): else: return ab_pb2.SeekPosition(specified = ab_pb2.SeekSpecified(number = position)) +def convertSeek(utfString): + try: + return int(utfString) + except ValueError: + return str(utfString) + def createSeekInfo(chainID = TEST_CHAIN_ID, start = 'Oldest', end = 'Newest', behavior = 'FAIL_IF_NOT_READY'): return common_pb2.Envelope( payload = common_pb2.Payload( @@ -223,23 +244,12 @@ def createSeekInfo(chainID = TEST_CHAIN_ID, start = 'Oldest', end = 'Newest', b ).SerializeToString(), ) -def generateBroadcastMessages(chainID = TEST_CHAIN_ID, numToGenerate = 1, timeToHoldOpen = 1): + + +def generateBroadcastMessages(chainID = TEST_CHAIN_ID, numToGenerate = 3, timeToHoldOpen = 1, dataFunc =_defaultDataFunction, chainHeaderType=common_pb2.ENDORSER_TRANSACTION ): messages = [] for i in range(0, numToGenerate): - payload = common_pb2.Payload( - header = common_pb2.Header( - chainHeader = common_pb2.ChainHeader( - chainID = chainID, - type = common_pb2.ENDORSER_TRANSACTION, - ), - signatureHeader = common_pb2.SignatureHeader(), - ), - data = str("BDD test: {0}".format(datetime.datetime.utcnow())), - ) - envelope = common_pb2.Envelope( - payload = payload.SerializeToString() - ) - messages.append(envelope) + messages.append(dataFunc(i)) for msg in messages: yield msg time.sleep(timeToHoldOpen)