NULS设计文档解读——区块管理模块

官方新闻NULSNICE2020-03-13 12:16:04  阅读 -评论 0

摘要:NULS,让区块链更简单!

NULS设计文档解读——区块管理模块 为什么需要区块管理模块

区块链是一种加密的分布式记账技术,由全网所有节点共同维护区块链上的交易记录,最终形成一个分布式账本。在这个账本中,所有交易不是简单的堆叠在一起,而是按照交易时间,以区块为单元,相互串联起来的。

所以,我们也可以这样理解:交易组成区块,区块串联起来,组成账本。

区块作为区块链中保存交易的基本单元,有其对应的业务职责和处理逻辑。例如,当节点刚加入某条链时,需要先同步区块数据;节点将交易打包成区块之后,需要对区块进行签名、广播、验证等操作;节点不仅要自己参与打包区块,还要验证和存储其他节点广播给自己的区块。

NULS2.0是一个通用的区块链基础设施,采用的是微服务架构,会根据区块链系统的业务,将底层拆分成不同的模块。区块链系统对区块的处理,有许多共性,将系统中跟区块相关的处理逻辑,单独用一个功能模块实现,不仅可以很好地为其他模块提供统一的区块数据服务,还能进一步提升系统的模块化程度。

区块管理模块功能

区块管理模块功能体现了该模块的作用,也是开发该模块需要达到的目标。读者阅读本文档的目标是,理解区块管理模块具有哪些功能,以及这些功能的实现流程。

在NULS2.0中,共识模块负责发起区块打包操作,从区块打包开始,一个区块处理的全流程就开始了。根据区块的处理流程,我们将区块管理模块的主要功能分为:区块验证、区块存储、区块广播、区块转发、区块同步、分叉链切换。

NULS设计文档解读——区块管理模块

下面我们详细介绍以上功能。

区块验证

当共识模块组装好区块,完成区块签名之后,会将区块发送给区块管理模块,由区块管理模块进行区块验证。区块验证主要分为基础验证、分叉/孤儿区块验证。

基础验证:当区块管理模块收到共识模块发送来的区块信息之后,首先是对协议版本、时间戳、梅克尔哈希等区块头信息,进行正确性验证。

分叉/孤儿区块验证:

要明白分叉/孤儿区块验证,就需要先明白区块与链的四种关系,我们假设存在区块a和链A,它们可能存在的四种关系如下:

1、区块a在链A上已经存在,说明区块a在链A中属于重复区块,将会被直接丢弃;

2、区块a属于链A上的分叉块,这意味着链A上,此时在同一高度存在不低于2个有可能会被记录上链的区块(出现了分叉链),此时区块管理模块会在内存中存储区块a的区块头信息,等待后续处理;

3、区块a能与链A之前的区块能串联起来,说明区块a是可以直接进行存储的;

4、区块a与链A以及其他分叉链都没有关联关系,说明区块a是孤儿块。

在进行分叉/孤儿区块验证的时候,会依次根据以上4种情况进行验证:

如果验证结果是重复区块,直接丢弃,否则,进行第2种情况的验证;如果验证结果是分叉块,在内存中暂存分叉块的区块头信息,否则,进行第3种情况的验证;如果验证结果是能与主链串联起来的块,则等待执行区块存储流程,否则,进行第4中情况的验证;如果验证结果是孤儿块,内存中会暂时缓存孤儿块的区块头。 区块存储

在NULS2.0中,无论是节点自己打包的区块,还是其他节点广播或转发过来的区块,都会先进行区块验证,然后再进行存储。

区块存储主要分为两种情况:主链区块存储和分叉链/孤儿链区块存储。

存储主链区块

在NULS2.0中,支持多链并行和跨链,所以NULS主网需要支持多条链的数据存储,不同链的区块存到不同的表中,表名加chainID作为后缀,进行区分。一个完整的区块由区块头和交易组成,区块头与交易分别进行存储,区块头存储在区块管理模块中,交易存储在交易管理模块中。在区块管理模块中,主链区块存储表的数据结构如下图所示:

NULS设计文档解读——区块管理模块 NULS设计文档解读——区块管理模块

在存储主链区块时,主要有以下三个流程:

进行区块验证,验证通过,执行下面的流程;区块管理模块发起交易业务验证,交易模块执行交易验证的相关流程,对交易的业务规则、合法性等进行验证;以上验证全部通过,由其他模块分别对自己需要负责的交易进行执行,执行成功,各个模块保存自己需要保存的数据,区块管理模块根据主链区块存储表的数据结构,保存相关数据。如果执行失败,区块管理模块回滚相关区块数据,其他模块回滚相关交易数据。 存储分叉链/孤儿链区块

存储分叉链/孤儿链区块与存储主链区块不同的是,内存中会缓存所有分叉链与孤儿链对象,但是只记录起始高度、起始Hash、结束高度、结束Hash等关键信息,在硬盘中,会缓存全量的区块数据。

这样做是因为,当需要进行分叉链切换、清理分叉链等操作时,只需读取一次数据库即可。

在进行存储时,不同的链存储在不同的表中,表名加上chainID作为后缀,进行区分。在区块管理模块中,分叉链/孤儿链区块存储表的数据结构如下图所示:

NULS设计文档解读——区块管理模块

进行区块验证之后,如果是分叉/孤儿块,会根据上面的表结构存储相关数据,同时,内存中也会缓存上面说到的相关数据,但因为不是主链区块,所以还不能进行最终的确认存储,需要根据后续出块的情况,进行分叉链切换、清理分叉链等操作。

区块广播

当进行区块打包的节点完成区块验证之后,就需要将自己打包的区块广播给其他节点,让其他节点进行验证和存储。区块广播主要分为以下3个主要流程:

在完成区块验证之后,根据区块信息,将区块头和交易哈希列表组装成SmallBlockMessage,广播给与自身相连的节点;收到广播消息的节点,根据交易哈希列表,判断哪些交易是本地没有的,然后根据交易哈希列表,组装HashListMessage发送给广播节点,从广播节点获取本地没有的交易;广播节点收到HashListMessage消息之后,组装TxGroupMessage,将请求方没有的交易,发送给请求方。请求方收到包括区块头、区块交易等完整区块信息之后,区块广播完成。 区块转发

区块转发是相对区块广播而言的,如果节点A打包了一个区块a,节点A将区块a广播给了节点B,那么节点B在完成区块验证之后,将区块a发送给节点C的过程,就被称为区块转发

区块转发主要流程:

进行区块转发的源节点,对区块进行验证之后,使用区块哈希组装HashMessage消息,转发给与自己相连的目标节点;目标节点在收到转发的HashMessage之后,会根据区块哈希,判断是否收到过对应的SmallBlock:如果没有收到过,根据区块哈希,先返回GetSmallBlockMessage消息给源节点,获取SmallBlock;如果收到过,直接进入下面的流程。目标节点判断 SmallBlock中的所有交易,本地是否都已全部保存:如果有交易本地未保存,就根据交易信息,组装HashListMessage发送给源节点,请求获取缺失的交易。源节点收到消息后,会将缺失的交易发送给目标节点;如果交易都已保存在本地,直接进入下面的流程。根据SmalBlock和完整的交易数据,目标节点会组装完整的区块,并进行保存;目标节点重复以上流程,向除了源节点以外的节点进行区块转发。 区块同步

当有新的节点被创建成功时,节点需要先同步区块,让本地的区块高度与网络中大部分节点保持一致。如果节点出现故障,中途掉线,重新启动之后,也需要先同步区块。区块同步主要分为以下4个流程:

当节点与网络正常连接之后,会从其他节点中获取所有区块,直到达到主网最新的区块高度,节点会判断本地的区块高度,是否高于网络中的区块高度:如果高于网络中的区块高度,则不进行区块同步;如果低于网络中的区块高度,则进行区块同步,进入下面的流程。根据本地区块高度与网络中的区块高度的高度差,判断需要从哪一个高度开始同步区块,然后将需要同步的区块分成若干个区块范围,向与自己建立连接的节点,分别发送不同范围高度的区块的下载请求;将从其他节点下载的区块,存放到一个集合中,直到所有区块下载成功。如果中途,有区块下载失败,会尝试重新下载;所有区块下载成功之后,根据高度依次从集合中取出区块,进行区块验证和存储。 分叉链切换

在NULS2.0中,当出现分叉链时,如果分叉链的高度已经高于主链,并超过系统设定的链切换阀值,将会进行主链与分叉链的切换,也就是遵循最长链原则。分叉链切换的主要流程如下:

找到主链与分叉链的分叉点,根据分叉点,找出主链与分叉链的链切换路径;回滚主链上处于链切换路径上的区块,回滚掉的区块组成新的分叉链,链接到新主链上;依次添加链切换路径上的区块,组成新的主链。

以上流程仅凭文字,很难理解,我们通过图示,来加以解释。

NULS设计文档解读——区块管理模块

如上图所示,假设分叉链1与分叉链2,都达到了链切换阀值的高度,此时将启动分叉链切换:

首先,需要找到链切换路径。分叉链1的分叉点,到分叉链2的分叉点之间的区块,属于分叉链1中,需要切换到新主链的区块,分叉链2从分叉点开始,一直到自己最新高度的区块,都需要切换到新主链上。确定了新主链的区块,就需要回滚原主链上的区块,所以原主链上,从分叉链1的分叉点开始往后的所有区块,回滚后组成新的分叉链;分叉链1,从分叉链2的分叉点开始,一直到分叉链1的最新高度的区块,组成另一条新的分叉链。图中标有红色阴影部分的区块,都属于链切换路径上的区块,将他们串联在一起,组成新的主链。 其他 消息协议 区块高度信息HeightMessage 消息说明:用于"区块同步"过程中重试下载 Length Fields Type Remark 64 heighrt int64 区块高度 单个摘要消息HashMessage 消息说明:用于"区块转发","孤儿链维护"功能 Length Fields Type Remark 32 hash byte[] 交易hash 摘要列表消息HashListMessage 消息说明:用于"区块转发"功能 Length Fields Type Remark 32 blockHash byte[] 区块hash ? hashLength VarInt 数组长度 32 hash byte[] 交易hash 区块广播消息SmallBlockMessage 消息说明:用于"区块转发"、"区块广播"功能 Length Fields Type Remark ? preHash byte[] preHash ? merkleHash byte[] merkleHash 32 time Uint32 时间 32 height Uint32 区块高度 32 txCount Uint32 交易数 ? extendLength VarInt extend数组长度 ? extend byte[] extend 32 publicKeyLength Uint32 公钥数组长度 ? publicKey byte[] 公钥 ? signBytesLength VarInt 签名数组长度 ? signBytes byte[] 签名 ? txHashListLength VarInt 交易hash列表数组长度 ? txHashLength VarInt 交易hash数组长度 ? txHash byte[] 交易hash 高度区间消息HeightRangeMessage 消息说明:用于"区块同步"功能 Length Fields Type Remark 64 startHeight int64 起始高度 64 endHeight int64 结束高度 完整的区块消息BlockMessage 消息说明:用于"区块同步" Length Fields Type Remark 32 requestHash byte[] requestHash 32 preHash byte[] 上一个区块的hash 32 merkleHash byte[] merkleHash 32 time Uint32 时间 32 height Uint32 区块高度 32 txCount Uint32 交易数 ? extendLength VarInt extend数组长度 ? extend byte[] extend 32 publicKeyLength Uint32 公钥数组长度 ? publicKey byte[] 公钥 ? signBytesLength VarInt 签名数组长度 ? signBytes byte[] 区块签名 16 type uint16 交易类型 32 time uint32 交易时间 ? remarkLength VarInt 备注数组长度 ? remark byte[] 备注 ? txDataLength VarInt 交易数据数组长度 ? txData byte[] 交易数据 ? coinDataLength VarInt CoinData数组长度 ? coinData byte[] CoinData ? txSignLength VarInt 交易签名数组长度 ? txSign byte[] 交易签名 1 syn byte 是否是为区块同步请求的区块 请求完成消息CompleteMessage 消息说明:通用消息,用于异步请求,标志异步请求处理结束。 Length Fields Type Remark 32 Hash byte[] Hash 1 success byte 成功标志 交易列表的消息TxGroupMessage 消息说明:用于"区块转发" Length Fields Type Remark 32 blockHash byte[] blockHash ? txCount VarInt 交易数 16 type uint16 交易类型 32 time uint32 交易时间 ? remarkLength VarInt 备注数组长度 ? remark byte[] 备注 ? txDataLength VarInt 交易数据数组长度 ? txData byte[] 交易数据 ? coinDataLength VarInt CoinData数组长度 ? coinData byte[] CoinData ? txSignLength VarInt 交易签名数组长度 ? txSign byte[] 交易签名 模块配置

{ "forkChainsMonitorInterval": 10000, "orphanChainsMonitorInterval": 10000, "orphanChainsMaintainerInterval": 5000, "storageSizeMonitorInterval": 300000, "networkResetMonitorInterval": 300000, "nodesMonitorInterval": 5000, "txGroupRequestorInterval": 1000, "txGroupTaskDelay": 3000, "testAutoRollbackAmount": 0, "blockMaxSize": 5242880, "resetTime": 180000, "chainSwtichThreshold": 3, "cacheSize": 1000, "heightRange": 1000, "maxRollback": 1000, "consistencyNodePercent": 60, "minNodeAmount": 1, "downloadNumber": 10, "extendMaxSize": 1024, "validBlockInterval": 60000, "smallBlockCache": 6, "orphanChainMaxAge": 10, "singleDownloadTimeout": 10000, "waitNetworkInterval": 5000, "cachedBlockSizeLimit": 20971520, "genesisBlockPath": "" } 区块管理模块启动时需要依赖的模块 NULS设计文档解读——区块管理模块

声明:链世界登载此文仅出于分享区块链知识,并不意味着赞同其观点或证实其描述。文章内容仅供参考,不构成投资建议。投资者据此操作,风险自担。此文如侵犯到您的合法权益,请联系我们kefu@lianshijie.com

参与讨论 (0 人参与讨论)

相关推荐

美国最高审计机构开发区块链技术应用程序原型

美国最高审计机构开发区块链技术应用程序原型

暴走时评:美国最高审计机构政府责任办公室发布了其创新实验室下的两个新职位,涉及3月的区块链技术应用程序原型的开发。展望未来,Young预计GAO的“围绕区块链技术的监督工作”将继续增长。

三家公司向你展示在区块链上配对另一半是什么样子的?

区块链能够提供的最重要的贡献是验证机制。数据安全和隐私是区块链可以解决的。区块链不仅消除了缺陷,还缩小了对理想缺陷的搜索范围。AI和区块链将简化这一过程,并根据用户的个人信息和选择为他们提供服务。

区块链技术在iGaming行业中有未来吗?

以其他方式使用区块链加密货币并不是区块链技术应用于iGaming行业的唯一方式,尽管说除了少数独立操作外,加密货币是唯一的解决方案。区块链技术为整个世界和iGaming行业提供了许多令人兴奋的可能性。

Pantera Capital合伙人:投机是加密货币目前阶段最重要应用

律动 BlockBeats 消息,区块链投资机构 Pantera Capital 合伙人 Paul 在接受超对称资本合伙人刘懿的访谈中表示,目前,投机仍然是加密货币最重要的应用;流动性和可扩展性仍然是实现大规模去中心化应用之前需要解决的关键挑战。

Conflux研究院 :详解Conflux代付费机制

Conflux研究院 :详解Conflux代付费机制

「羊毛真的出在猪身上?!」Conflux 代付费机制说了这么多,那么 Conflux 是如何解决这个问题的呢?因此,Conflux 从协议层面设计了一个为调用智能合约的交易代付交易费的赞助者(Spon

SEC暂缓对BCT代币发行的调查,该项目创始人同时涉及另一起刑事案件

这两家公司都在起诉 Manor 和其副手 Pardo 涉嫌欺诈性的 BCT 代币发行。

区块链AMA到底有没有用?

区块链AMA到底有没有用?

靠 AMA 能有多少用户转化、用户买买买?区块链 KOL 配合 AMA 达成活动运营目标将起到事倍功半的效果,带来更大的活动传播、达成共识!让 AMA 不成为一场独幕剧,不当冤大头撒红包雨!

区块链钱包的未来 – 生存还是毁灭

区块链钱包系列文章的第一篇 《钱包的未来 – 生存还是毁灭》撰文:比特派钱包首席运营官,王超作者序:哥,搞这么多年钱包,挣钱不?作为链上身份的容器,大量日常行为都会和区块链钱包产生关系。

麦妖榜
更新日期 2019-09-03
排名用户贡献值
1牛市来了30910
2BitettFan24187
3等待的宿命23810
4区块大康20369
5六叶树20310
6linjm122719429
7天下无双16192
8lizhen00215280
9让时间淡忘14586
10yelanyi050511349
返回顶部 ↑