Channel Configuration (configtx)

Hyperledger 패브릭 블록 체인 네트워크의 공유 구성은 채널 당 하나의 컬렉션 구성 트랜잭션에 저장됩니다. 각 구성 트랜잭션은 일반적으로 더 짧은 이름 configtx로 참조 됩니다.

채널 구성에는 다음과 같은 중요한 속성이 있습니다.

  1. Versioned : 구성의 모든 요소에는 모든 수정 작업을 수행 할 수 있는 관련 버전이 있습니다. 또한 커밋된 모든 구성은 시퀀스 번호를 받습니다.
  2. Permissioned : 구성의 각 요소에는 해당 요소에 대한 수정이 허용되는지 여부를 결정하는 관련 정책이 있습니다. 이전 configtx 사본이 있고 추가 정보가 없는 사용자는 이 정책을 기반으로 새 구성의 유효성을 확인할 수 있습니다.
  3. Hierarchical : 루트 구성 그룹에는 하위 그룹이 포함되며 계층 구조의 각 그룹에는 연관된 값과 정책이 있습니다. 이러한 정책은 계층을 활용하여 하위 수준의 정책에서 한 수준의 정책을 유도합니다.

Anatomy of a configuration

구성은 다른 트랜잭션이 없는 블록에 HeaderType_CONFIG 유형의 트랜잭션으로 저장됩니다. 이러한 블록을 구성 블록(Configuration Blocks) 이라고하며 , 그 중 첫 번째 블록을 기원 블록(Genesis Block) 이라고 합니다.

구성을 위한 프로토 구조는 fabric/protos/common/configtx.proto에 저장됩니다. HeaderType_CONFIG 유형의 언벨로프(Envelope)는 Payload data 필드로 ConfigEnvelope 메시지를 인코딩합니다. ConfigEnvelope의 프로토 타입은 다음과 같이 정의됩니다 :

message ConfigEnvelope {
    Config config = 1;
    Envelope last_update = 2;
}

이 last_update 필드는 아래의 구성 업데이트 섹션에서 정의되지만 구성을 검증할 때만 필요합니다. 대신 현재 커밋된 구성은 Config 메시지를 포함하는 config 필드에 저장됩니다.

message Config {
    uint64 sequence = 1;
    ConfigGroup channel_group = 2;
}

sequence 번호는 커밋된 구성마다 하나씩 증가합니다. channel_group 필드는 구성을 포함하는 루트 그룹입니다. ConfigGroup 구조는 재귀 정의되며, 각 그룹에는 값과 정책을 포함하는 각각의 그룹의 트리를 구축합니다. 그것은 다음과 같이 정의됩니다 :

message ConfigGroup {
    uint64 version = 1;
    map<string,ConfigGroup> groups = 2;
    map<string,ConfigValue> values = 3;
    map<string,ConfigPolicy> policies = 4;
    string mod_policy = 5;
}

ConfigGroup은 재귀적 구조이므로 계층적인 배열을가집니다. 다음 예는 golang 표기법을 명확하게 표현한 것입니다 :

// Assume the following groups are defined
var root, child1, child2, grandChild1, grandChild2, grandChild3 *ConfigGroup

// Set the following values
root.Groups["child1"] = child1
root.Groups["child2"] = child2
child1.Groups["grandChild1"] = grandChild1
child2.Groups["grandChild2"] = grandChild2
child2.Groups["grandChild3"] = grandChild3

// The resulting config structure of groups looks like:
// root:
//     child1:
//         grandChild1
//     child2:
//         grandChild2
//         grandChild3

각 그룹은 구성 계층에서 수준을 정의하며 각 그룹은 관련된 값 집합 (문자열 키로 인덱싱 됨)과 정책 (문자열 키로 인덱싱 됨)을 갖습니다.

값은 다음과 같이 정의됩니다 :

message ConfigValue {
    uint64 version = 1;
    bytes value = 2;
    string mod_policy = 3;
}

정책은 다음과 같이 정의됩니다 :

message ConfigPolicy {
    uint64 version = 1;
    Policy policy = 2;
    string mod_policy = 3;
}

값, 정책 및 그룹에는 모두 version과 mod_policy가 있습니다. 요소의 version은 해당 엘리먼트가 수정 될 때마다 증가됩니다. mod_policy는 해당 요소를 수정하는 데 필요한 서명을 적용하는 데 사용됩니다. 그룹의 경우 수정은 값, 정책 또는 그룹 맵에 요소를 추가하거나 제거하는 것입니다 (또는 mod_policy 변경). 값 및 정책의 경우 수정은 값 및 정책 필드를 각각 변경합니다 (또는 mod_policy 변경). 각 요소의 mod_policy는 현재 구성 수준의 컨텍스트에서 평가됩니다. Channel.Groups["Application"]에 정의된 다음 mod 정책 예제를 고려하십시오 (여기서 golang 맵 참조 구문을 사용하므로Channel.Groups["Application"].Policies["policy1"]은 기본 Channel 그룹의 Application 그룹의 Policies 맵 policy1 정책을 참조하십시오).

  • policy1은 Channel.Groups["Application"].Policies["policy1"]에 매핑됩니다.
  • Org1/policy2Channel.Groups["Application"].Groups["Org1"].Policies["policy2"]에 매핑됩니다.
  • /Channel/policy3은 Channel.Policies["policy3"]에 매핑됩니다.

mod_policy가 존재하지 않는 정책을 참조하는 경우 해당 항목을 수정할 수 없습니다.

Configuration updates

구성 업데이트는 HeaderType_CONFIG_UPDATE 유형의 Envelope 메시지로 제출됩니다. 트랜잭션의 Payload data는 marshaled된 ConfigUpdateEnvelope입니다. ConfigUpdateEnvelope는 다음과 같이 정의됩니다.

message ConfigUpdateEnvelope {
    bytes config_update = 1;
    repeated ConfigSignature signatures = 2;
}

이 signatures 필드에는 구성 업데이트를 인증하는 일련의 서명이 들어 있습니다. 메시지 정의는 다음과 같습니다 :

message ConfigSignature {
    bytes signature_header = 1;
    bytes signature = 2;
}

signature_header는 표준 트랜잭션에 정의된 대로 서명은 signature_header 바이트와 ConfigUpdateEnvelope 메시지의 config_update 바이트의 연결을 넘습니다.

ConfigUpdateEnvelope config_update 바이트는 다음과 같이 정의된 marshaled된 ConfigUpdate 메시지입니다 :

message ConfigUpdate {
    string channel_id = 1;
    ConfigGroup read_set = 2;
    ConfigGroup write_set = 3;
}

channel_id는 업데이트가 바인딩된 채널 ID이며, 이 재구성을 지원하는 서명의 범위를 지정하는 데 필요합니다.

read_set은 version 필드만 설정되고 다른 필드는 채워져서는 안되는 것으로 지정된 기존 구성의 하위 집합을 지정합니다. 특정 ConfigValue value 또는 ConfigPolicy policy 필드는 read_set에 절대로 설정해서는 안됩니다. ConfigGroup은 config 트리의 더 깊은 요소를 참조할 수 있도록, 맵 필드의 하위 집합을 채울 수 있습니다. 예를 들어, Application 그룹을 read_set에 포함시키려면 그 부모 (Channel 그룹)도 읽기 세트에 포함되어야하지만 Channel 그룹은 모든 키를 채울 필요가 없습니다. Orderer group 키 또는 아무 valuespolicies 키 중 하나를 선택하십시오.

write_set는 수정된 구성을 지정합니다. 구성의 계층적 특성으로 인해 계층 구조의 깊숙한 요소에 대한 쓰기는 해당 write_set 계층의 상위 수준 요소를 포함해야합니다. 그러나, 동일한 버전의 read_set에도 지정된 write_set의 요소는 read_set에서와 같이 드문드문하게 지정해야 합니다.

예를 들어, 구성이 주어진 경우 :

Channel: (version 0)
    Orderer (version 0)
    Appplication (version 3)
       Org1 (version 2)

Org1을 수정하는 구성 업데이트를 제출하려면 read_set이 다음과 같습니다 :

Channel: (version 0)
    Application: (version 3)

write_set은 다음과 같습니다.

Channel: (version 0)
    Application: (version 3)
        Org1 (version 3)

CONFIG_UPDATE가 수신되면 orderer는 다음을 수행하여 결과 CONFIG를 계산합니다.

  1. channel_id및 read_set을 확인합니다. read_set의 모든 요소는 지정된 버전에 존재해야합니다.
  2. read_set에 동일한 버전으로 나타나지 않는 write_set의 모든 요소를 ​​수집하여 업데이트 세트(update set)를 계산합니다 .
  3. 업데이트 세트의 각 요소가 요소 업데이트의 버전 번호를 정확히 1만큼 증가시키는 지 확인합니다.
  4. ConfigUpdateEnvelope에 첨부된 서명 세트가 업데이트 세트의 각 요소에 대해 mod_policy를 충족하는지 확인합니다.
  5. 업데이트 세트를 현재 구성에 적용하여 새로운 전체 버전의 구성을 계산합니다.
  6. 새 구성을 ConfigEnvelope에 기록하고 CONFIG_UPDATE를 last_update 필드로, config 필드에 인코딩된 새 구성을 증가된 sequence 값과 함께 기록합니다.
  7. 새 ConfigEnvelope를 CONFIG 유형의 Envelope에 기록하고 궁극적으로 이것을 새로운 구성 블록에 단독 트랜잭션으로 씁니다.

피어 (또는 다른 Deliver 수신자)가 이 구성 블록을 수신하면 현재 구성에 last_update 메시지를 적용하고 순서대로 계산된 config 필드에 올바른 새로운 구성이 들어 있는지 확인하여 구성이 적절하게 유효성이 검증되었는지 확인해야합니다 .

Permitted configuration groups and values

유효한 구성은 다음 구성의 서브 세트입니다. 여기서 우리는 peer.<MSG> 표기법을 사용하여 value 필드가 fabric/protos/peer/configuration.proto에 정의된 <MSG> 이름의 marshaled된 프로토 메시지임을 나타내는 ConfigValue를 정의합니다. common.<MSG>msp.<MSG> 및 orderer.<MSG>의 표기법은 비슷하지만, fabric/protos/common/configuration.proto, fabric/protos/msp/mspconfig.protofabric/protos/orderer/configuration.proto에서 정의된 메시지를 사용합니다.

키 {{org_name}}과 {{consortium_name}}은 임의의 이름을 나타내며 다른 이름으로 반복될 수 있는 요소를 나타냅니다.

&ConfigGroup{
    Groups: map<string, *ConfigGroup> {
        "Application":&ConfigGroup{
            Groups:map<String, *ConfigGroup> {
                {{org_name}}:&ConfigGroup{
                    Values:map<string, *ConfigValue>{
                        "MSP":msp.MSPConfig,
                        "AnchorPeers":peer.AnchorPeers,
                    },
                },
            },
        },
        "Orderer":&ConfigGroup{
            Groups:map<String, *ConfigGroup> {
                {{org_name}}:&ConfigGroup{
                    Values:map<string, *ConfigValue>{
                        "MSP":msp.MSPConfig,
                    },
                },
            },

            Values:map<string, *ConfigValue> {
                "ConsensusType":orderer.ConsensusType,
                "BatchSize":orderer.BatchSize,
                "BatchTimeout":orderer.BatchTimeout,
                "KafkaBrokers":orderer.KafkaBrokers,
            },
        },
        "Consortiums":&ConfigGroup{
            Groups:map<String, *ConfigGroup> {
                {{consortium_name}}:&ConfigGroup{
                    Groups:map<string, *ConfigGroup> {
                        {{org_name}}:&ConfigGroup{
                            Values:map<string, *ConfigValue>{
                                "MSP":msp.MSPConfig,
                            },
                        },
                    },
                    Values:map<string, *ConfigValue> {
                        "ChannelCreationPolicy":common.Policy,
                    }
                },
            },
        },
    },

    Values: map<string, *ConfigValue> {
        "HashingAlgorithm":common.HashingAlgorithm,
        "BlockHashingDataStructure":common.BlockDataHashingStructure,
        "Consortium":common.Consortium,
        "OrdererAddresses":common.OrdererAddresses,
    },
}

Orderer system channel configuration

Ordering 시스템 채널은 Ordering 매개 변수와 채널 생성을 위한 컨소시엄을 정의해야 합니다. Ordering 서비스를 위해서는 정확히 하나의 Ordering 시스템 채널이 있어야하며, 생성된 (또는 더 정확하게 부트스트랩 된) 첫 번째 채널입니다. Ordering 시스템 채널 기원(genesis) 구성 내에서 응용 프로그램 섹션을 정의하지 않는 것이 좋습니다. 그러나 테스트를 위해 수행할 수 있습니다. Ordering 시스템 채널에 대한 읽기 권한을 가진 회원은 모든 채널 생성을 볼 수 있으므로 이 채널의 액세스가 제한되어야합니다.

Ordering 매개 변수는 config의 다음 서브 세트로 정의됩니다.

&ConfigGroup{
    Groups: map<string, *ConfigGroup> {
        "Orderer":&ConfigGroup{
            Groups:map<String, *ConfigGroup> {
                {{org_name}}:&ConfigGroup{
                    Values:map<string, *ConfigValue>{
                        "MSP":msp.MSPConfig,
                    },
                },
            },

            Values:map<string, *ConfigValue> {
                "ConsensusType":orderer.ConsensusType,
                "BatchSize":orderer.BatchSize,
                "BatchTimeout":orderer.BatchTimeout,
                "KafkaBrokers":orderer.KafkaBrokers,
            },
        },
    },

ordering에 참여하는 각 조직에는 Orderer 그룹 아래에 그룹 요소가있습니다. 이 그룹은 해당 조직에 대한 암호화 신원 정보를 포함하는 단일 매개 변수 MSP를 정의합니다. Orderer 그룹의 Values에 따라 Orderer 노드가 작동하는 방식이 결정됩니다. 채널마다 존재하므로 orderer.BatchTimeout은 한 채널에서 다른 채널과 다르게 지정될 수 있습니다.

시작시, orderer는 많은 채널에 대한 정보가 들어있는 파일 시스템에 직면하게됩니다. orderer는 컨소시엄 그룹이 정의된 채널을 식별하여 시스템 채널을 식별합니다. 컨소시엄 그룹의 구조는 다음과 같습니다.

&ConfigGroup{
    Groups: map<string, *ConfigGroup> {
        "Consortiums":&ConfigGroup{
            Groups:map<String, *ConfigGroup> {
                {{consortium_name}}:&ConfigGroup{
                    Groups:map<string, *ConfigGroup> {
                        {{org_name}}:&ConfigGroup{
                            Values:map<string, *ConfigValue>{
                                "MSP":msp.MSPConfig,
                            },
                        },
                    },
                    Values:map<string, *ConfigValue> {
                        "ChannelCreationPolicy":common.Policy,
                    }
                },
            },
        },
    },
},

각 컨소시엄은 ordering 조직의 조직 구성원과 마찬가지로 구성원 집합을 정의합니다. 각 컨소시엄은 ChannelCreationPolicy 또한 정의합니다. 이 정책은 채널 생성 요청을 승인하는 데 적용됩니다. 일반적으로 이 값은 채널의 새 구성원이 채널 생성을 승인하도록 요구하는 ImplicitMetaPolicy로 설정됩니다. 채널 생성에 대한 자세한 내용은이 문서 뒷부분에 나와 있습니다.

Application channel configuration

애플리케이션 구성은 애플리케이션 유형 트랜잭션을 위해 설계된 채널을 위한 것입니다. 그것은 다음과 같이 정의됩니다 :

&ConfigGroup{
    Groups: map<string, *ConfigGroup> {
        "Application":&ConfigGroup{
            Groups:map<String, *ConfigGroup> {
                {{org_name}}:&ConfigGroup{
                    Values:map<string, *ConfigValue>{
                        "MSP":msp.MSPConfig,
                        "AnchorPeers":peer.AnchorPeers,
                    },
                },
            },
        },
    },
}

Orderer 섹션과 마찬가지로 각 조직은 그룹으로 인코딩됩니다. 그러나 MSP 신원 정보만 인코딩하는 대신 각 조직은 AnchorPeers의 목록을 추가로 인코딩합니다. 이 목록은 다른 조직의 피어가 피어 가십 네트워킹(peer gossip networking)을 위해 서로 접촉할 수 있게 합니다.

응용 프로그램 채널은 이 매개 변수의 결정적 업데이트를 허용하기 위해 oderer org 및 합의(consensus) 옵션의 사본을 인코딩하므로 orderer 시스템 채널 구성의 동일한 Orderer 섹션이 포함됩니다. 그러나 응용 프로그램 관점에서 이것은 크게 무시 될 수 있습니다.

Channel creation

orderer가 존재하지 않는 채널에 대해 CONFIG_UPDATE를 수신하면, orderer는 이것이 채널 작성 요청이어야한다고 가정하고 다음을 수행합니다.

  1. orderer는 채널 생성 요청이 수행될 컨소시엄을 식별합니다. 최상위 레벨 그룹의 Consortium 값을 보고 이를 수행합니다 .
  2. orderer는 Application그룹에 포함된 조직이 해당 컨소시엄에 포함된 조직의 하위 집합이며 ApplicationGroup이 version 1로 설정되어 있는지 확인합니다.
  3. orderer는 컨소시엄에 회원이 있는 경우 새 채널에도 애플리케이션 회원 (생성 컨소시엄 및 멤버가 없는 채널은 테스트에만 유용함)이 있는지 확인합니다.
  4. orderer는 ordering 시스템에서 Orderer 그룹을 가져와서 새로 지정된 멤버로 Application 그룹을 만들고 해당 mod_policy를 컨소시엄 구성에 지정된대로 ChannelCreationPolicy로 지정하여 템플릿 구성을 만듭니다. 정책은 새로운 구성 컨텍스트에서 평가되므로 ALL 구성원을 요구하는 정책에는 컨소시엄의 모든 구성원이 아닌 모든 새 채널 구성원의 서명이 필요합니다.
  5. 그러면 orderer는 CONFIG_UPDATE를 이 템플릿 구성에 대한 갱신 사항으로 적용합니다. CONFIG_UPDATEApplication 그룹 (해당 version은 1)에 수정 사항을 적용하기 때문에 구성 코드는 ChannelCreationPolicy에 대해 이러한 업데이트의 유효성을검사합니다. 채널 생성에 개별 조직의 앵커 피어 (peer peer)와 같은 다른 수정 사항이 포함되어있는 경우 요소에 해당하는 mod 정책이 호출됩니다.
  6. 새 채널 구성을 사용하는 새로운 CONFIG 트랜잭션은 ordering 시스템 채널에서 ordering을 위해 포장되어 전송됩니다. ordering 후에 채널이 생성됩니다.

출처 : http://hyperledger-fabric.readthedocs.io/en/release-1.1/configtx.html

+ Recent posts