NEAR共识机制

1. 引言

NEAR采用PoS共识机制,使用名为NighShade的分片设计,采用名为DoomSlug的区块生成机制。

2. 相关定义及符号

为了维护共识,交易会打包进区块。存在一个preconfigured block G G G,称为genesis block。除 G G G之外,每个block都有a link pointing to the previous block p r e v ( B ) prev(B) prev(B),其中 B B B为block,通过该link最终可连接到 G G G(不存在cycles)。

  • A < B A<B A<B:即意味着 A ≠ B A\neq B A=B,且 B B B可通过previous block link连接到 A A A
  • A ≤ B A\leq B AB:即意味着 A < B A<B A<B A = B A=B A=B
  • A ∼ B A\sim B AB:即意味着 A < B A<B A<B A = B A=B A=B A > B A>B A>B
  • A ≁ B A\nsim B AB:即为非 A ∼ B A\sim B AB

chain c h a i n ( T ) chain(T) chain(T):是指a set of blocks reachable from block T T T,称为tips,即 c h a i n ( T ) = { B ∣ B ≤ T } chain(T)=\{B|B\leq T\} chain(T)={BBT}。对于任意的区块 A , B A,B A,B,当且仅当 A ∼ B A\sim B AB时, A , B A,B A,B之间存在a chain。此时,可成 A , B A,B A,B在同一链上。

每个区块都有一个整数height h ( B ) h(B) h(B)。区块高度是单调递增的,即对于任意的区块 B ≠ G B\neq G B=G,有 h ( B ) > h ( p r e v ( B ) ) h(B)>h(prev(B)) h(B)>h(prev(B))。但不要求区块高度是连续的,如 h ( G ) h(G) h(G)可不为0。每个节点keep track of a valid block with the largest height it knows about, which is called its head。

区块会打包进epoch。在链上,属于同一epoch的一组区块形成连续的范围:若区块 A < B A<B A<B都属于同一epoch,则每个满足 A < X < B A<X<B A<X<B的区块 X X X都属于该epoch。epoch可 以sequential indices来标记: G G G属于index为0的epoch;对于每个block B B B,其所属epoch index要么等于 p r e v ( B ) prev(B) prev(B)的epoch index,要么大于。

每个epoch关联 a set of block producers that are validating blocks in that epoch, as well as an assignment of block heights to block producers that are responsible for producing a block at that height。

负责生产高度为 h h h区块的block producer称为block proposer at h h h

epoch index i ≥ 2 i\geq 2 i2 的validator set和block height assignment信息会在epoch index为 i − 2 i-2 i2的最后一个block确定。对于epoch index为0和1的情况,其validator set和block height assignment为preconfigured的。因此,若2链共享某epoch的最后一个区块,则其后续2个epoch具有相同的validator set和相同的block height assignment,但是对于再更后的epoch则无法保证。

固化:若block B B B固化了,则任何未来的固化区块都是仅能基于 B B B构建的。因此,在 B B B及之前区块的交易将永远不会被reverse。 f i n a l ( B , T ) final(B,T) final(B,T),其中 B ≤ T B\leq T BT,意味着 B B B c h a i n ( T ) chain(T) chain(T)上固化了。若 f i n a l ( B , T ) final(B,T) final(B,T)为真,则对于所有的 T ′ ≥ T T'\geq T TT f i n a l ( B , T ′ ) final(B,T') final(B,T)均为真。

2. Data structures

NEAR区块头中与共识相关的字段有:

struct BlockHeader {
    ...
    prev_hash: BlockHash,
    height: BlockHeight,
    epoch_id: EpochId,
    last_final_block_hash: BlockHash,
    approvals: Vec<Option<Signature>>
    ...
}

在特定epoch的block producers会交换多种类型的消息,与共识相关的消息有2种:

  • Blocks
  • Approvals

具体包含了以下字段:

enum ApprovalInner {
    Endorsement(BlockHash),//为the hash of the approved block
    Skip(BlockHeight),//为the height of the approved block 
}

struct Approval {
    inner: ApprovalInner,
    target_height: BlockHeight,//为the specific height at which the approval can be used (an approval with a particular `target_height` can be only included in the `approvals` of a block that has `height = target_height`)
    signature: Signature,//为对`(inner, target_height)`的签名
    account_id: AccountId //为the account of the block producer who created the approval
}

3. Approvals Requirements

除genesis block之外的每个区块 B B B中,都必须逻辑上包含来自于block producers的approvals,这些block producers的累计stake必须超过该epoch中总stake的2/3。在epoch切换时,要求block producers的累计stake需超过下一epoch总stake的2/3。

approval有2种类型:

  • 当且仅当 h ( B ) = h ( p r e v ( B ) ) + 1 h(B)=h(prev(B))+1 h(B)=h(prev(B))+1时,为Endorsement
  • 否则为Skip with the height of p r e v ( B ) prev(B) prev(B)

存储在区块中的每个approval逻辑上对于每个block producer都是相同的(除了account_idsignature不同),因此, 存储所有approvals是冗余的。事实物理上值存储了signatures of the approvals,具体的存储方式为:

  • 获取当前epoch的block producers ordered set。

若某block在epoch边界,也需要包含approvals form the next epoch,因此需要add new accounts from the new epoch:

def get_accounts_for_block_ordered(h, prev_block):
    cur_epoch = get_next_block_epoch(prev_block)
    next_epoch = get_next_block_next_epoch(prev_block)

    account_ids = get_epoch_block_producers_ordered(cur_epoch)
    if next_block_needs_approvals_from_next_epoch(prev_block):
        for account_id in get_epoch_block_producers_ordered(next_epoch):
            if account_id not in account_ids:
                account_ids.append(account_id)

    return account_ids

因此,该边界block中包含了a vector of optional signatures of the same or smaller size than the resulting set of account_ids, with each element being Noneif the approval for such account is absent, or the signature on the approval message if it is present。因此,很容易根据区块中的信息重构出签名approvals的block producers,并验证相应的签名。若the vector of signature短于account_ids的长度,则剩余的signatures均假设为None

4. Messages

当收到approval消息,参与者仅将其存入the collection of approval messages中:

def on_approval(self, approval):
    self.approvals.append(approval)

当参与者收到一个block,与共识相关的操作有:

  • 更新head
  • 初始化a timer来开始发送该block的approvals给the block producers at the consecutive target_heights。计时器超时时间取决于俄最后固化区块的高度,该信息也会persisted。
def on_block(self, block):
    header = block.header

    if header.height <= self.head_height:
        return

    last_final_block = store.get_block(header.last_final_block_hash)

    self.head_height = header.height
    self.head_hash = block.hash()
    self.largest_final_height = last_final_block.height

    self.timer_height = self.head_height + 1
    self.timer_started = time.time()

    self.endorsement_pending = True

定时器会定期检查如下逻辑:

def get_delay(n):
    min(MAX_DELAY, MIN_DELAY + DELAY_STEP * (n-2))

def process_timer(self):
    now = time.time()

    skip_delay = get_delay(self.timer_height - self.largest_final_height)

    if self.endorsement_pending and now > self.timer_started + ENDORSEMENT_DELAY:

        if self.head_height >= self.largest_target_height:
            self.largest_target_height = self.head_height + 1
            self.send_approval(head_height + 1)

        self.endorsement_pending = False

    if now > self.timer_started + skip_delay:
        assert not self.endorsement_pending

        self.largest_target_height = max(self.largest_target_height, self.timer_height + 1)
        self.send_approval(self.timer_height + 1)

        self.timer_started = now
        self.timer_height += 1

def send_approval(self, target_height):
    if target_height == self.head_height + 1:
        inner = Endorsement(self.head_hash)
    else:
        inner = Skip(self.head_height)

    approval = Approval(inner, target_height)
    send(approval, to_whom = get_block_proposer(self.head_hash, target_height))

其中get_block_proposer返回的下一block proposer。

同时要求ENDORSEMENT_DELAY < MIN_DELAY,尽管不影响正确性,NEAR中要求ENDORSEMENT_DELAY * 2 <= MIN_DELAY

5. Block Production

定义了获取特定高度区块中approvals的函数:

def get_approvals(self, target_height):
    return [approval for approval
                     in self.approvals
                     if approval.target_height == target_height and
                        (isinstance(approval.inner, Skip) and approval.prev_height == self.head_height or
                         isinstance(approval.inner, Endorsement) and approval.prev_hash == self.head_hash)]

只要get_approvals返回的approvals中对应的block producers的累计质押量超过了总质押量的2/3,被指定该高度的产块者即可产块。

6. 固化条件

block B B B固化在 c h a i n ( T ) chain(T) chain(T),其中 T ≥ B T\geq B TB,要么 B = G B=G B=G,要么block X ≤ T X\leq T XT 使得 B = p r e v ( p r e v ( X ) ) 且 h ( X ) = h ( p r e v ( X ) ) + 1 = h ( B ) + 2 B=prev(prev(X)) 且 h(X)=h(prev(X))+1=h(B)+2 B=prev(prev(X))h(X)=h(prev(X))+1=h(B)+2。即,要么 B B Bwei genesis block,要么 c h a i n ( T ) chain(T) chain(T)包含至少2个blocks on top of B B B,且这3个区块(包含区块 B B B本身及其后续2个区块)具有连续的区块高度。

7. epoch切换

e p o c h l e n g t h ≥ 3 epoch_{length}\geq 3 epochlength3定义了一个epoch的最小长度。假设某epoch e c u r e_{cur} ecur开始于高度 h h h,下一个epoch为 e n e x t e_{next} enext

B P ( e ) BP(e) BP(e)为epoch e e e中的一系列产块者。
l a s t f i n a l ( T ) last_{final(T)} lastfinal(T)为the highest final block in c h a i n ( T ) chain(T) chain(T)

则产块者产块中包含的approvals规则为:

  • 1)对于高度为 h ( p r e v ( B ) ) < h + e p o c h l e n g t h − 3 h(prev(B))< h+epoch_{length}-3 h(prev(B))<h+epochlength3的区块 B B B属于epoch e c u r e_{cur} ecur,必须有超过2/3的approvals of B P ( e c u r ) BP(e_{cur}) BP(ecur)(stake-weighted)。
  • 2)对于高度为 h ( p r e v ( B ) ) ≥ h + e p o c h l e n g t h − 3 h(prev(B))\geq h+epoch_{length}-3 h(prev(B))h+epochlength3 h ( l a s t f i n a l ( p r e v ( B ) ) ) < h + e p o c h l e n g t h − 3 h(last_{final(prev(B))})<h+epoch_{length}-3 h(lastfinal(prev(B)))<h+epochlength3的区块 B B B属于epoch e c u r e_{cur} ecur,必须同时拥有超过2/3的approvals of B P ( e c u r ) BP(e_{cur}) BP(ecur)(stake-weighted) 以及 超过2/3的approvals of B P ( e n e x t ) BP(e_{next}) BP(enext)(stake-weighted)。
  • 3)对于第一个高度为 h ( l a s t f i n a l ( p r e v ( B ) ) ) ≥ h + e p o c h l e n g t h − 3 h(last_{final(prev(B))})\geq h+epoch_{length}-3 h(lastfinal(prev(B)))h+epochlength3 区块 B B B属于epoch e n e x t e_{next} enext,必须有超过2/3的approvals of B P ( e n e x t ) BP(e_{next}) BP(enext)(stake-weighted)。

8. Safety

honest block producer:

  • 永远无法为同一prev_height生成2个endorsement(即冲突的endorsements)
  • 永远无法生成a skip message s 和 an endorsement e e e,使得s.prev_height < e.prev_height and s.target_height >= e.target_height(即冲突的skip和endorsement)

有定理:
在这里插入图片描述
有推论:
在这里插入图片描述
在这里插入图片描述

9. Liveness

具体proof of liveness见 NEAR团队2020年论文 《Doomslug: block confirmation with single round of communication, and a finality gadget with guaranteed liveness》。此处的共识不同之处在于要求2个连续具有endorsements的区块。而在论文中的proof进行了扩展,之处,一旦the delay is sufficiently long for a honest block producer to collect enough endorsements, the next block producer ought to have enough time to collect all the endorsements too。

10. Approval condition

approval condition为:

  • 任何有效的区块内,必须包含approvals from block producers,其累计质押量超过该epoch中总质押量的2/3。对于区块 B B B及其前一区块 B ′ B' B,当且仅当B.height == B'.height + 1时, B B B中的每个approval必须为an Endorsement with the hash of B ′ B' B,否则必须为a Skip with the height of B ′ B' B

这2个条件无法合一。对于approval中的endorsement,其prev_hash必须等于the hash of the previous block,否则上面第7节的safety proof将无法通过。

对于skip messages来说,不要求approval中的hash匹配the hash of the previous block,因为若有malicious actor可在同一高度创建2个区块,并将其分别分发给一半的block producers。每一半的block producers将给同一prev_height发送具有不同prev_hash的skip messages 给未来的产块者。若此时要求skip中的prev_hash必须严格匹配区块的prev_hash,则将没有产块者可创建新的区块。

参考资料

[1] NEAR 共识机制
[2] What is NEAR protocol?
[3] Doomslug vs PBFT, Tendermint, and Hotstuff
[4] NEAR团队2020年论文 《Doomslug: block confirmation with single round of communication, and a finality gadget with guaranteed liveness

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值