Channel Configuration(configtx)

Channel Configuration(configtx)

Hyperledger Fabric区块链网络的共享配置存储在一个collection configuration transaction中,每个通道一个。每个configuration transaction通常由较短的名称 configtx引用。

channel配置具有以下重要属性:

  • versioned:配置的所有元素都有一个关联的版本,每个修改行为都会使版本产生一次变更。此外,每个提交的配置接收序列号。
  • Permissioned:配置的每个元素都有一个关联的策略,用于管理是否允许修改该元素。任何具有以前的configtx(和没有附加信息)的副本的人都可以基于这些策略来验证新配置的有效性。
  • Hierarchical:根配置组包含子组,层次结构的每一组都具有关联的值和策略。这些策略可以利用层次结构,从较低级别的策略中获得一个级别的策略。

配置剖析

配置被存储在类型为HeaderType_CONFIG的transaction中,该transaction存放在一个没有其他transaction的块中。这些块被称为configuration blocks,其中第一个被称为genesis block。

用于配置的原始结构存储在 fabric/protos/common/configtx.protoHeaderType_CONFIG类型的envelope 编码一个ConfigEnvelope消息作为 Payload data字段。原型ConfigEnvelope定义如下:

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

last_update字段在“ 更新配置”部分中定义,但仅在验证配置时才需要,而不是读取它。相反,当前提交的配置存储在config字段中,其中包含一条Config消息。

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

每次提交配置sequence的数字增加1。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是一个递归结构,它具有层次化的排列。以下示例:

// 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都在配置的当前级别的上下文中进行评估。请考虑以下定义的示例mod策略Channel.Groups["Application"](Here, we use the golang map reference syntax, so Channel.Groups["Application"].Policies["policy1"] refers to the base Channel group’s Application group’s Policies map’s policy1 policy)。

  • policy1 映射到 Channel.Groups["Application"].Policies["policy1"]
  • Org1/policy2 映射到 Channel.Groups["Application"].Groups["Org1"].Policies["policy2"]
  • /Channel/policy3 映射到Channel.Policies["policy3"]
    请注意,如果mod_policy引用不存在的策略,则不能修改该项。

配置更新

配置更新作为HeaderType_CONFIG_UPDATE类型的Envelope消息提交。交易的Payload data是一个ConfigUpdateEnvelopeConfigUpdateEnvelope定义如下:

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

signatures字段包含授权配置更新的一组签名。其消息定义是:

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

signature_ header是按照标准transaction定义的,签名是来自ConfigUpdateEnvelope消息的signature_ header字节和config_update字节的级联。

ConfigUpdateEnvelope config_update字节是一个编组 ConfigUpdate消息,其定义如下:

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

channel_id是更新绑定的channel ID,这是必要的,以确定·哪些签名支持这个重置。

read_set指定了现有的配置的一个子集,其中只有version字段被设置,并且没有其他字段必须被填充。特定ConfigValue valueConfigPolicy policy字段永远都不应该在read_set中设置。ConfigGroup可能有映射字段的子集被填充,以便引用在配置树更深的元素。例如,要将Application组包含在read_set中,其父(Channel组)也必须包含在read_set中,但Channel组不需要填充所有键,例如Orderer group键或任何一个valuespolicies键。

write_set指定被修改的配置的部分。由于配置的层次性,write_set中要写入某深层元素必须包含较高级别的元素。然而,对于write_set中的任意元素必须在read_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通过执行以下操作:

  • 检验channel_idread_setread_set中的所有元素必须在给定版本中存在。
  • 通过收集write_set中的所有元素来计算更新集,其中不会出现和read_set相同的版本。
  • 验证更新集中的每个元素的版本是否都增加了1。
  • 验证附加到ConfigUpdateEnvelope的签名集是否满足更新集中每个元素的`mod_policy
  • 通过将更新集应用于当前配置来计算新的配置完整版本。
  • 将新的配置写成ConfigEnvelope其中包括 CONFIG_UPDATE作为last_update字段,新的配置编码在config字段中,且具有增加的sequence值。
  • 将新的ConfigEnvelope写成CONFIG类型的Envelope中,最终将此作为唯一的交易写入新的配置块。

当peer(或任何其他接收到Deliver的节点)接收到此配置块时,它应通过将last_update消息应用于当前配置并验证orderer计算的config字段是否包含正确的新配置来验证该配置是否有效。

允许的配置组和值

任何有效的配置都是以下配置的一个子集。在这里,我们使用符号peer.<MSG>定义一个ConfigValue,其value字段是在fabric/protos/peer/configuration.proto中定义的名为<MSG>的marshaled proto message。符号common.<MSG>msp.<MSG>orderer.<MSG>类似,但他们的消息定义在fabric/protos/common/configuration.protofabric/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系统通道配置

ordering system channel需要定义ordering参数,以及用于创建channel的联盟。ordering服务必须只有一个ordering system channel,它是要创建的第一个channel。建议不要在ordering system channel genesis configuration中定义应用程序部分,但可以进行测试。请注意,具有读取访问ordering system channel权限的任何成员可能会看到所有channel的创建,因此这个channel的访问权限应受到限制。

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的organization都有一个在Orderer下group元素。这个group定义了MSP ,它包含该组织的加密身份信息。Orderer组的value值确定ordering节点的功能。它们在每个channel中存在,例如每个channel的orderer.BatchTimeout可能是不一样的。

在启动时,orderer面临着包含许多channel信息的文件系统。orderer通过识别带有consortiums group定义的channel来识别system channel。consortiums group有以下结构:

&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,
                    }
                },
            },
        },
    },
},

请注意,每个consortium定义一组成员,就像ordering orgs的organizational members。每个consortium也定义一个ChannelCreationPolicy。这是一种应用于授权channel创建请求的策略。通常,该值将被设置为ImplicitMetaPolicy要求channel的新成员签名来授权channel创建。有关频道创建的更多详细信息,请参见本文档之后的内容。

应用通道配置

application configuration用来配置为应用程序类型的transaction设计的channel。定义如下:

&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部分一样,每个organization都被编码为一个group。然而,不仅编码MSP身份信息,每个organization另外编码一个AnchorPeers列表。该列表允许不同组织的peer彼此联系。

application channel编码一个orderer组织和共识选项的副本,以允许确定性更新这些参数,因此orderer system channel configuration中的Orderer部分包括在其中。但从应用的角度看,这可能在很大程度上被忽略。

创建channel

当orderer收到一个对不存在的channel的CONFIG_UPDATE时,orderer假定这一定是channel创建请求,并执行以下操作。

  • orderer通过查看识别channel创建请求中高级别group的consortium值来识别consortium。
  • orderer验证包含在Applicationgroup中的organization是包含在相应consortium中的organization的子集,并且ApplicationGroup设置version为1。
  • orderer核实,如果consortium有成员,新channel也有application成员(创建没有成员的consortium和channel仅对测试有用)。
  • orderer通过从ordering system channel中提取orderergroup创建创建模板配置 ,并创建一个带有新指定成员的Applicationgroup并指定其mod_policyChannelCreationPolicy依照在consortium config中指定的。请注意,该策略是在新配置的上下文中进行评估,因此一个需要ALL成员的策略将需要所有新channel成员的签名,而不是consortium的所有成员。
  • 然后,orderer将CONFIG_UPDATE作为更新应用于此模板配置。因为CONFIG_UPDATEApplicationgroup(版本是1)有修改,config code会根据ChannelCreationPolicy验证这些更新的有效性。如果创建channel包含任何其他的修改,比如一个org的anchor peers,那么相应的修改策略会被调用。
  • 带有新channel配置的新CONFIGtransaction被wrapped并发送到ordering system channel上排序。排序后,创建channel。

==============================================================
如果有转载请注明出处!

[英文原版]

configtx

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值