Fabric记录

原创
2018/04/13 17:01
阅读数 325

Fabric记录

[TOC]

Architecture

系统架构

Transactions

  1. 部署合约的交易
  2. 调用合约的交易
  3. 纯查询的交易
  4. 合约交叉调用的

Blockchain datastructures

State

区块链的状态是通过带版本的键值对进行存储的,链码通过putget这两种 KVS 操作进行读写。

状态sK->(V,N)的映射组成,其中:

  • K是键的集合
  • V是值的集合
  • N是有序版本号的集合

VN有一个⊥的元素,代表空类型

对于任意k,我们有:s(k)=(v,ver)。两种KVS 操作如下:

  • put(k,v),以 s 作为初始撞死,以 s'作为结束状态,满足:

    1.s'(k)=(v,next(s(k).version))

    2.对于k'!=k,有s'(k')=s(k')

  • get(k) 返回 s(k)

Ledger
  • PeerLedger

    与 OrdererLedger 的区别是,还维护了一个区别是否有效 transaction 的 bitmask

  • OrdererLedger

Nodes

Client
Peer

特殊的接收 client 提案的 peer,叫做__endorser__

Orderer

排序服务对 clients 和 peers 提供一个共享的通信频道(channel),channel 提供消息投递的原子性。

Partitioning。Orderer 提供多个 channel,clients 可以按需订阅。

Ordering service API。Peers 通过 API 连接到 orderer 提供的 channel,两个基础的 API 如下:

  1. broadcast(blob),client 调用
  2. deliver(seqno, prevhash, blob),orderer 调用用来通知 peer

排序服务特性

  1. 安全性(一致性保证)。广播的消息是一个一个块deliver(seqno, prevhash, blob),后一个块有前一个的 hash,即区块链。
  2. 活性(投递保证)。

交易背书工作流

client 创建交易并发送到 endorser

问题:endorser 是如何确定的?一个 org 只有一个 endorser 么?这个 endorser 和 leader peer 是同一个么?

endorser 是合约维度的,一个合约在配置背书策略的时候,会配置 endorser,比如:

peer chaincode instantiate -C <channelid> -n mycc -P "AND('Org1.member', 'Org2.member')"

其中 Org1.member, Org2.member就是 endorser,这里的 endorser 表示的是哪个 org,但 org 里面还有多个 peer。另一种说法,实例化合约的 peer 就是 endorser。合约必须只被安装在 endorser 上以保证合约代码的机密性。

PROPOSE消息格式

<PROPOSE,tx,[anchor]>,其中:

  • tx=<clientID,chaincodeID,txPayload,timestamp,clientSig>

    对于不同的交易类型,txPayload有所不同

    • 调用合约交易 txPayload = <operation, metadata>
      • operation:调用的函数及参数
      • metadata:相关的属性
    • 部署合约交易 txPayload = <source, metadata, policies>
      • source:链码
      • metadata:相关的属性
      • policies:背书策略,需要注意的是,这里只给出背书策略的 ID 以及对应的参数
  • anchor 版本号,如果有这个字段,那么 endorser 在背书的时候会检查对应的 key 是不是等于指定的 version

client 会将tid=HASH(tx)保存在内存中,等待 endorser 的反馈

endorser 模拟交易并签名

endorser 收到请求后进行如下操作:

  1. 验证 clientSig

  2. 如果指定了anchor则先检查 version

  3. 模拟交易,获取 readsetwriteset

  4. 生成tran-proposal发往背书模块(endorsing logic) 默认直接接受并进行签名,*但是也可以进行任意操作,将tran-proposaltx作为输入发往相关系统获得判定是否要进行背书。*背书逻辑调用的是系统默认的合约 ESCC,当然也可以自己编写背书合约,但是这始终是一个同步调用操作,不用也不能由人工介入。

  5. 如果决定背书,则向提交请求的 client 发送: <TRANSACTION-ENDORSED, tid, tran-proposal,epSig>,这个大概就是**endorsement**吧?

    tran-proposal := (epID,tid,chaincodeID,txContentBlob,readset,writeset)txContentBlob是与链码/交易有关系的信息(例如:txContentBlob=tx.txPayload

    epSig是 endorser 对tran-proposal的签名

  6. 如果背书失败,则发送(TRANSACTION-INVALID, tid, REJECTED)

client 收集背书结果并通过排序服务广播

根据背书策略,在收到足够的背书响应后,client 向 orderer 发起broadcast(blob)

orderer 发送交易到 peer

orderer 向 peer 发送 deliver(seqno, prevhash, blob),peer 收到后,做如下处理:

  1. 根据blob.tran-proposal.chaincodeID对应的合约检查blob.endorsement有效性
  2. 检查blob.endorsement.tran-proposal.readset的版本检查,默认使用串行的隔离级别
  3. PeerLedger的 bitmask 中标记该交易为有效,并应用结果集blob.endorsement.tran-proposal.writeset
  4. 如果背书策略检查失败,则在PeerLedger的 bitmask 中标记该交易为无效

image-20180408195818744

Gossip

gossip主要起到以下几个作用:

  1. 检测可用的 peer 以及监测 peer 是否存活
  2. 同步账本数据
  3. 将新连接上的 peer 数据更新

领头选举

每个 org 会选举出一个 leader peer(实际上可以存在多个),负责连接到 orderer。leader peer从orderer 拿到新块的信息后分发给其他 peer。

静态选主

可以在core.yaml中配置:

peer:
    # Gossip related configuration
    gossip:
        useLeaderElection: false
        orgLeader: true

也可以使用环境变量:

export CORE_PEER_GOSSIP_USELEADERELECTION=false
export CORE_PEER_GOSSIP_ORGLEADER=true

需要注意的是:

  1. 如果都配置为 false,那么 peer 不会尝试变成一个 leader
  2. 如果都配置为 true,会引发异常
  3. 静态配置的方式,需要自行保证 leader 的可用性
动态选主

选主具体算法不明,类似 raft选主,leader 需要向从节点发送心跳,动态选主只能产生1个主节点

可以在core.yaml中配置:

peer:
    # Gossip related configuration
    gossip:
        useLeaderElection: true
        orgLeader: false
        # 心跳频率
        election:
        	leaderAliveThreshold: 10s

也可以使用环境变量:

export CORE_PEER_GOSSIP_USELEADERELECTION=true
export CORE_PEER_GOSSIP_ORGLEADER=false

Gossip 消息

点对点通信的安全性是由TLS保证的,不需要签名,这里会不会有什么问题?

展开阅读全文
打赏
0
0 收藏
分享

作者的其它热门文章

加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部