块奖励计数及其状态平衡

一、EOS的奖励制度
??对记账节点的经济激励机制是区块链项目不可缺少的重要组成部分,EOS则是通过增发的方式来给予节点奖励,支付其工资。每年增发的EOS比率为5%左右,按照总供应量10亿来计算,就是五千万EOS。

通胀的EOS用途:

??如上图,通胀的EOS币先发行到系统账户eosio中,其中的20%, 用于节点奖励;另外80%,用于EOS基金池,会在未来用于社区福利应用或者对EOS系统有所帮助的项目。该部分资金存入eosio.saving系统账户中。
??EOS节点分为两类:出块节点(Block Producer,常缩写为BP),备用节点(Block Producer Candidate)。EOS主网之中,设定得票为前21个节点为出块节点,其他的节点为备用节点。
??通胀作为节点奖励的那20%EOS,又分为两部分发放:
???? 25%用作出块奖励,按照一定的分配原则平均分配给21个出块节点。
???? 75%用作投票奖励,根据节点投票权重占比分配给出块节点和备用节点。
??出块节点得到的奖励是出块奖励投票奖励两部分奖励之和,备用节点只能得到投票奖励,奖励额不足100 EOS,则无法获得奖励。
??出块奖励只向21个出块节点发放,其中涉及到一个出块奖励池的概念,由于每个节点领取时都会增发部分EOS,所以所有未领取的出块奖励都会放在出块奖励池中等待节点领取。每次单个节点领取时,能领取到的出块奖励数量计算公式如下:
??单个节点可领取的数量=出块奖励池里的EOS数量 * 该BP未领取奖励的出块数量 / 所有未领取奖励的区块数量
??由此看出节点出块数量,是节点领取奖励的重要依据,那节点出块数量是由谁统计又怎么实现共识的呢,下面我们会对这两点进行展开介绍。

二、节点出块量统计
??出块节点每出一个块,都会创建一个出块量累计交易(后面我们会叫块奖励交易),执行该交易会触发系统合约on_block动作,增加db状态库的出块量计数。

??生产节点每次出块前,会先准备块环境,主要是准备pending块,这部分够工作由chain/controller.cpp中的controller_impl::start_block函数实现,该函数会初始化pending块的_pending_block_state,需要打包进块的交易都会放入该pending块,start_block函数结束前还会创建一个块奖励交易,并调用push_transaction()函数进行执行,该交易执行时,会调用系统合约的on_block动作。 on_block是一个很基础的合约动作,在eosio.system合约下的 producer_pay.cpp文件中,主要功能是添加出块量计数和重选出块节点。下面通过代码展示说明这个过程。
1) controller_impl::start_block()函数

构造块奖励交易:

??这里说明一下,系统启动起来,会创建默认特权账户eosio,在没有加载系统合约system_contract时,块奖励交易onblock动作的合约执行体是空,不会执行任何操作。只有加载系统合约system_contract eosioeosio账户后,才会真正调用该合约的onblock动作,进行块奖励累加计数操作。
2)交易执行:controller_impl::push_transaction()函数

3)在第2)步执行交易时,会根据1)中构造的交易体,执行onblock动作

4)出块时间到后,节点会打包pinding块,进行一些扫尾工作,对块进行签名完成本次出块动作。
三 、块奖励交易的共识及状态平衡实现
??细心的朋友肯定发现了,出块节点创建并执行了块奖励交易,将自己节点的db数据库中本节点出块数加一,但并没有打包到块里。那其它节点接收到该块,并不会收到该奖励交易,也就无从执行。那这笔块奖励交易是如何实现共识并保证节点间状态平衡的呢?
1、验证节点处理

??其实,其它生产节点作为验证节点在接收到新块后,先做了一些块验证操作,比如是否已经收到过该块,是否需要进行分叉处理等,通过验证处理后,就需要在节点内执行块中所有交易,保证节点间状态平衡。
??在执行块中交易前,也会和出块节点调用同样的函数controller_impl::start_block(),构造块处理环境,此时块奖励交易也同样会在收块节点创建并执行一遍。将块头所带的块生产者的出块值,在本节点db状态库中进行累加。实现了节点间该数据的状态平衡。

??有朋友可能要问了,节点接到块,就把生产者的出块数+1了,此时该块还没达到不可逆呢,万一后面在处理分叉时,该块被分叉废弃掉了,没有达到最终不可逆,那块奖励值还能减回来么?这就要感谢db状态库的回滚操作了,在需要废弃块时,会先对该块进行回滚操作,这笔块奖励交易也同样会被会滚掉的。
??上面讲的是块奖励交易的节点同步,也就是状态平衡的实现,但这笔交易没有挂在块上,块的全网共识是不包含此交易的,那块奖励交易的共识是如何实现的呢?
??这也是EOS实现巧妙的地方,需要各位自己理解啦,哈哈…。这里只简单提示一下,如果把这笔交易放到块中,由块共识,验证节点直接执行块中交易实现同步。那生产节点创建奖励交易时,可以多创建个几十次放到块上,那其它节点同步时,是不是也就同步了几十次,其实生产者只生产了一次块,却实现了几十次的计数,怎么规避?这样,由验证者收到块后,自行创建完成块奖励计数。是不是自动实现共识了呢?
2、块重播时处理
??块奖励交易不在块上,也就不会写入block_log文件中,那在节点重启需要通过块重播进行数据恢复时,块奖励交易如何写入db状态库的呢?其实理解了验证节点该操作的处理方式,这点就不难理解了。块重播,每次播放块中交易前,也要先调用controller_impl::start_block()构造pending块,这个块奖励交易的构造执行过程也就被执行了。
四、链接
星河公链

原文地址:https://blog.51cto.com/14267585/2415367

时间: 2024-10-24 10:40:07

块奖励计数及其状态平衡的相关文章

bzoj 4401 块的计数 思想+模拟+贪心

块的计数 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 455  Solved: 261[Submit][Status][Discuss] Description 小Y最近从同学那里听说了一个十分牛B的高级数据结构——块状树.听说这种数据结构能在sqrt(N)的时间内维护树上的各种信息,十分的高效.当然,无聊的小Y对这种事情毫无兴趣,只是对把树分块这个操作感到十分好奇.他想,假如能把一棵树分成几块,使得每个块中的点数都相同该有多优美啊!小Y很想知

bzoj 4401: 块的计数

根据块状树的那堆理论可以发现,对于某种块大小,可行的分法只有一种 如果一个点能被当成块顶,仅当其子树大小是块大小的倍数 于是枚举块的大小\(i\),当可行的块顶个数大于等于\(n / i\)时,就可以构造出可行的分法了 时间复杂度 \(O(\sum_{d|n}d)\) #include <bits/stdc++.h> #define N 2010000 using namespace std; int n; int lt[N], bi[N], nt[N], tl; int si[N], ai[

【bzoj4401】块的计数

首先,块的大小确定的话,可以发现方案最多只有1种 然后就可以O(nsqrt(n))搞,不过会TLE 接着我们又发现,一个节点可以作一个块的根,当且仅当该节点的size能被块的大小整除 然后就可以O(nlogn)搞了 #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> usi

bzoj4401 块的计数

首先确定一个根后dfs一遍,统计出每个子树的点数个数,然后枚举n的因子x,统计多少子树的点数个数是当前枚举因子x的倍数,如果有n/x个子树满足条件,则答案+1 代码 1 #include<cstdio> 2 #include<algorithm> 3 #include<set> 4 #define fi first 5 #define sc second 6 #define mp make_pair 7 #define N 2000100 8 using namespa

HDFS内副本和块的状态分析

前言 在HDFS内,我们通常听到的最频繁的2个名词术语:副本(Replica)和块(Block).几乎可以这么说,HDFS所有涉及到文件的操作都与这两个词相关.但是大家可能对这2个概念的理解还仅仅停留在一个比较浅的层面:比如说就是一个单一的replica或是一个单一的block块.尤其是在对块的层面,一个block块在最终完成后,它会经历哪些状态过程呢?这些细节的内容就是本文所准备阐述的. 副本/块的状态 在了解副本.块在文件的写入过程中的状态变化情况之前,我们需要对它们所有可能存在的状态做一个

计数类问题专题

主要是前两天被uoj的毛爷爷的题虐的不轻,心里很不爽啊,必须努力了,, 计数类问题分为:1.组合数学及数论计数 2.dp:状态压缩dp,插头轮廓线dp,树形dp,数位dp,普通dp 3.容斥原理 4.polya原理 5.图论计数 6.生成函数 7.其它(生成树计数等等) 本文主要研究前3个内容 考虑基本计数原理:加法原理,减法原理,乘法原理,除法原理 计数的基本原则:结果不重不漏 加法原理比较自然,中间过程有时减法原理 考虑到无向,有向图的各种量值(生成树之类)计数,状态压缩dp解决 论文:ht

Nginx流量带宽请求状态统计(ngx_req_status)

介绍 ngx_req_status 用来展示 nginx 请求状态信息,类似于 apache 的 status, nginx 自带的模块只能显示连接数等等 信息,我们并不能知道到底有哪些请求.以及各 url 域名所消耗的带宽是多少. ngx_req_status 提供了这些功能 按域名. url. ip 等等统计信息 统计总流量 统计当前带宽\峰值带宽 统计总请求数量 安装   # cd /usr/local/src/ # wget "http://nginx.org/download/ngin

nginx流量带宽等请求状态统计( ngx_req_status)

介绍 ngx_req_status用来展示nginx请求状态信息,类似于apache的status,nginx自带的模块只能显示连接数等等信息,我们并不能知道到底有哪些请求.以及各url域名所消耗的带宽是多少.ngx_req_status提供了这些功能. 功能特性 按域名.url.ip等等统计信息 统计总流量 统计当前带宽\峰值带宽 统计总请求数量 1. 安装 # cd /usr/local/src/ # wget "http://nginx.org/download/nginx-1.4.2.t

HDU 5441 Travel (并查集+数学+计数)

题意:给你一个带权的无向图,然后q(q≤5000)次询问,问有多少对城市(城市对(u,v)与(v,u)算不同的城市对,而且u≠v)之间的边的长度不超过d(如果城市u到城市v途经城市w, 那么需要城市u到城市w的长度e1≤d,同时城市w到城市v的长度e2≤d). 析:一开始的时候,题意都读错了,怎么看都不对,原来是只要最大的d小于等于x就可以,过了好几天才知道是这样..... 这个题是并查集的应用,先从d小的开始遍历,然后去判断有几个连通块,在连通块中计数,用一个数组即可,运用排列组合的知识可以知