首页> 中国专利> 一种更新状态默克树的方法及装置

一种更新状态默克树的方法及装置

摘要

本说明书实施例提供一种更新状态默克树的方法和装置,其中状态默克树用于存储区块链网络中账户的状态。方法包括以下步骤:首先,确定状态默克树中由账户的状态变化导致需要更新的待更新节点;然后,根据待更新节点,从状态默克树中提取出第一子树和M个第二子树,第一子树包含状态默克树的根节点,每个第二子树的根节点为待更新节点,且为第一子树中最底层节点的子节点。然后,将M个第二子树分配给N个工作线程,使得N个工作线程至少部分并行地处理M个第二子树,得到更新后的各个第二子树;于是,至少基于更新后的各个第二子树的根节点的哈希值,更新第一子树,从而得到更新后的状态默克树。

著录项

  • 公开/公告号CN110688377A

    专利类型发明专利

  • 公开/公告日2020-01-14

    原文格式PDF

  • 申请/专利权人 阿里巴巴集团控股有限公司;

    申请/专利号CN201910816557.5

  • 发明设计人 陆钟豪;

    申请日2019-08-30

  • 分类号G06F16/22(20190101);G06F16/23(20190101);G06Q20/38(20120101);

  • 代理机构11309 北京亿腾知识产权代理事务所(普通合伙);

  • 代理人陈霁;周良玉

  • 地址 英属开曼群岛大开曼资本大厦一座四层847号邮箱

  • 入库时间 2023-12-17 06:17:37

法律信息

  • 法律状态公告日

    法律状态信息

    法律状态

  • 2020-07-17

    授权

    授权

  • 2020-02-11

    实质审查的生效 IPC(主分类):G06F16/22 申请日:20190830

    实质审查的生效

  • 2020-01-14

    公开

    公开

说明书

技术领域

本说明书一个或多个实施例涉及区块链技术领域,尤其涉及更新区块链中用于记录账户状态的状态默克树的方法及装置。

背景技术

在新一代区块链中,例如在以太坊中,新增了账户的概念,相应地,用户可以通过区块链平台创建账户。在这样的场景中,区块链平台作用为区块链网络中的节点,用户创建的账户为以太坊中的外部账户。此外,诸如以太坊的许多区块链平台支持智能合约,来执行更为丰富的交易。智能合约可以由用户创建,在创建之后也具有对应的合约账户。如此,区块链网络中的账户可以包括外部账户和合约账户。

在区块链网络的各个节点中,在节点本地的数据库中以状态默克树(Merkletree)的形式维持区块链中全部账户(包括外部账户和合约账户)的状态数据。随着区块链中交易的执行,账户状态会发生变化,这就需要更新状态默克树。由于区块链网络中账户众多,交易执行频繁,因此,常常需要频繁地对状态默克树进行更新。

因此,需要一种有效的方案,能够更加高效地对记录账户状态的状态默克树进行更新,以提升区块链网络的整体性能。

发明内容

本说明书一个或多个实施例描述了一种更新状态默克树的方法及装置,通过并行处理的方式,提高状态默克树的更新效率,提升区块链网络的整体性能。

根据第一方面,提供了一种更新状态默克树的方法,所述状态默克树用于存储区块链网络中账户的状态,所述方法通过区块链网络中任意节点执行,包括:

确定所述状态默克树中由所述账户的状态变化导致需要更新的待更新节点;

根据所述待更新节点,从所述状态默克树中提取出一个第一子树和M个第二子树,所述第一子树包含所述状态默克树的根节点,所述M个第二子树两两之间没有交集,每个所述第二子树的根节点为待更新节点,且为所述第一子树中最底层节点的子节点;其中M为大于1的整数;

将所述M个第二子树分配给N个工作线程,使得所述N个工作线程至少部分并行地处理所述M个第二子树,得到更新后的各个第二子树;其中N为大于1的整数;

至少基于所述更新后的各个第二子树的根节点的哈希值,更新所述第一子树,从而得到更新后的状态默克树。

根据一种实施方式,在确定状态默克树中由所述账户的状态变化导致需要更新的待更新节点之前,上述方法还包括,执行交易集合中的各条交易,确定所述各条交易涉及的账户的状态变化。

进一步的,在一个实施例中,上述交易集合可以为从本地交易池中选定的多条交易构成的集合;在这样的情况下,在得到更新后的状态默克树之后,可以将所述交易集合打包到待生成的第一区块中,并将所述更新后的状态默克树的根节点的哈希值记录到所述第一区块中。

在另一实施例中,上述交易集合可以为待验证区块中包含的交易构成的集合;在这样的情况下,在得到更新后的状态默克树之后,可以将所述更新后的状态默克树的根节点的哈希值与所述待验证区块中记录的状态根的值进行比较,以验证所述待验证区块。

根据一种实施方式,通过以下方式确定所述状态默克树中的待更新节点:在所述状态默克树中,从状态发生变化的各个账户所对应的各个叶节点向根节点回溯,将回溯路径上经过的所有节点确定为所述待更新节点。

在一个实施例中,通过以下方式提取第一子树:在所述状态默克树中,提取从根节点到预定层数的节点,作为所述第一子树。

在另一实施例中,通过以下方式提取第一子树:在所述状态默克树中,从根节点开始按照宽度优先逐层遍历,如果当前层中待更新节点的数目大于或等于第一预设阈值,则提取从根节点到当前层的节点作为所述第一子树。

根据一种实施方式,通过以下方式提取第二子树:

获取所述第一子树的最底层节点中的待更新节点,作为第一节点集合;

获取第一节点集合中各个节点的子节点中的待更新节点,作为第二节点集合;

分别将第二节点集合中各节点作为起始节点,获取从各个起始节点直到叶节点的子树作为所述M个第二子树。

根据另一种实施方式,通过以下方式提取第一子树和第二子树:

在所述状态默克树中,从根节点开始按照宽度优先逐层遍历,如果当前层中待更新节点的数目大于或等于第二预设阈值,则提取从根节点到当前层的上一层的节点作为所述第一子树,并将当前层中各个待更新节点作为起始节点,获取从各个起始节点直到叶节点的子树作为所述M个第二子树。

在一个实施例中,通过以下方式将M个第二子树分配给N个工作线程:

分别对所述M个第二子树和所述N个工作线程进行编号,使得各个第二子树具有对应的第一编号,各个工作线程具有对应的第二编号;

对于所述M个第二子树中任意的第二子树,确定其对应的第一编号对N取模的结果,将其分配给第二编号为该取模结果的工作线程。

根据第二方面,提供了一种更新状态默克树的装置,所述状态默克树用于存储区块链网络中账户的状态,所述装置部署在区块链网络中任意节点中,包括:

节点确定单元,配置为确定所述状态默克树中由所述账户的状态变化导致需要更新的待更新节点;

子树提取单元,配置为根据所述待更新节点,从所述状态默克树中提取出一个第一子树和M个第二子树,所述第一子树包含所述状态默克树的根节点,所述M个第二子树两两之间没有交集,每个所述第二子树的根节点为待更新节点,且为所述第一子树中最底层节点的子节点;其中M为大于1的整数;

并行处理单元,配置为将所述M个第二子树分配给N个工作线程,使得所述N个工作线程至少部分并行地处理所述M个第二子树,得到更新后的各个第二子树;其中N为大于1的整数;

综合更新单元,配置为至少基于所述更新后的各个第二子树的根节点的哈希值,更新所述第一子树,从而得到更新后的状态默克树。

根据第三方面,提供了一种计算机可读存储介质,其上存储有计算机程序,当所述计算机程序在计算机中执行时,令计算机执行第一方面的方法。

根据第四方面,提供了一种计算设备,包括存储器和处理器,其特征在于,所述存储器中存储有可执行代码,所述处理器执行所述可执行代码时,实现第一方面的方法。

根据本说明书实施例提供的方法和装置,在需要更新状态默克树时,将状态默克树中需要更新的部分划分为位于上层的根子树,以及根子树以下多个相互独立的脏子树;然后利用多个工作线程并行对多个脏子树进行更新处理;最后基于各个工作线程对脏子树的更新结果,更新根子树,从而更新整个状态默克树。相比于传统的从叶节点逐层向上串行进行更新处理的方式,并行处理多个脏子树再进行汇总的方式可以显著提高状态默克树的更新效率,进而提高整个区块链网络的系统性能。

附图说明

为了更清楚地说明本发明实施例的技术方案,下面将对实施例描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本发明的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其它的附图。

图1是在一个实施例中区块结构示意图;

图2示出状态默克树的一个具体示例;

图3示出根据一个实施例的更新状态默克树的方法流程图;

图4示出在一个实施例中确定脏节点的示意图;

图5示出根据一个实施例提取的第一子树和第二子树的示意图;

图6示出根据一个实施例的状态默克树的更新装置的示意性框图。

具体实施方式

下面结合附图,对本说明书提供的方案进行描述。

如本领域技术人员所知,在区块链网络中,以区块的形式记录交易数据,新生成的区块经过网络中各个节点的共识之后,添加到区块链上,从而实现数据的不可篡改。图1是在一个实施例中区块结构示意图。需要理解,图1的区块结构是以以太坊为例进行举例说明的;其他区块链平台生成的区块结构可以与之略有不同。

如图1所示,区块链中每个区块至少包括区块头和交易列表,区块头中记录用于将本区块链接到区块链上的多种信息,包括父区块的哈希值,时间戳,要计算的随机数等等,交易列表中包含生成本区块的节点从交易池中选择收入本区块中的一系列交易。为了便于查找和验证账户状态和交易状态,以太坊的区块中还包括三棵默克树的根信息(root),这三棵默克树分别为状态树、交易树和收据树,相应的根信息分别为状态根、交易根和收据根。其中,状态默克树用于记录区块链网络中所有账户的状态信息,交易树用于记录本区块中的交易内容信息,收据树用于记录本区块中的交易收据信息。交易树和收据树为针对本区块中的交易一次性生成的默克树,一般不需要更新,而状态默克树则需要根据账户状态的变化频繁更新,因此,本说明书实施例中主要关注状态默克树。

状态默克树以树状结构存储状态键Key和状态值Value的对应关系,树中的节点通过哈希进行连接,即基于子节点生成哈希值,存储在父节点中。在记录账户状态的情况下,Key为账户地址,Value为账户状态或账户内容。在具体实施例中,该状态默克树例如可以是MPT(Merkle Patricia Tree)树,该MPT树的叶子节点为各个账户的账户状态,叶子节点上方的各个父节点包括账户地址的至少一个地址字符和对应于其全部子节点的哈希值。基于各层节点可以递归得到根节点的哈希值,该根哈希即为该状态树的状态根,记录在图1所示的区块中。

图2示出状态默克树的一个具体示例。在图2的示例中,状态默克树具体为MPT树,包括4个叶节点和叶节点到根节点之间的一系列枝干节点。4个叶节点分别对应于4个账户,叶节点的值即为账户的状态数据。具体地,对于外部账户来说,其状态数据可以包括,当前余额(balance),已发起交易序号(Nonce);对于合约账户来说,其状态数据进一步包括,合约代码的哈希,合约中变量的状态,其中合约变量的状态可以通过进一步的状态默克树来记录。在其他区块链中,账户的状态内容可以在以上举例基础上有所修改或添加,本说明书对此不作限定。

叶节点和根节点之间的每个枝干节点记录账户地址的一部分字符和一个哈希值,其中哈希值基于该枝干接点的各个子节点而确定。例如,叶节点1记录账户1的状态数据,该状态数据的哈希值记录于叶节点1的父节点,节点2中,即节点2中的哈希值基于其子节点,节点1的值而确定;节点3中的哈希值基于其两个子节点,节点2和节点4的哈希值而确定,如此继续向上递归,直到根节点。

此外,从根节点开始,沿节点的父子关系历经的各枝干节点中记录的地址字符共同构成对应账户的账户地址,所历经的路径构成通向对应账户的寻址路径。例如,沿着节点5->节点3->节点2的路径,各枝干节点中记录的地址字符共同构成账户1的账户地址。如此,通过图2所示的状态默克树,可以记录多个账户地址对应的多个账户的账户状态。

在另一示例中,可以在图2的MPT树的基础上进行进一步的改进、扩展。例如,在有些区块链平台中,在MPT树的节点关系和树结构的基础上,在状态默克树中进一步引入了扩展节点、分支节点,从而更有效地记录大量账户的账户地址和账户状态。

需要理解,以上图2仅仅是一个示例,用于说明状态默克树的具体形式。还可以存在其他具体形式的状态默克树,本说明书对此不作限定。

通过图2的示例可以看到,状态默克树中最底层的叶节点用于记录账户的状态数据。如本领域技术人员所知,随着区块链网络中交易的执行,账户的状态会发生改变。而根据以上状态默克树的结构设置,一旦叶节点的值发生变化,其父节点就需要更新其中的哈希值,进一步的一系列向上的父节点均需要更新哈希值。而区块链网络中交易的传播和执行是非常频繁的,因此,状态默克树就需要频繁的更新。

一般地,每次更新状态默克树时,从底层叶节点依次递归地向上更新各个父节点,直到更新根哈希。然而,由于记录全量账户的账户状态,状态默克树是一棵非常庞大的默克树。上述常规方式的计算效率仍然不能满足需要。

因此,在本说明书的实施例中,提出一种新的更新状态默克树的方法,其中,将状态默克树拆分为多个互相独立的、有待更新的子树,如此可以并行地更新处理各个子树,最后将更新结果合并,从而大幅提升状态默克树的更新效率。

图3示出根据一个实施例的更新状态默克树的方法流程图;该方法可以适用于公有链、私有链、联盟链,在此不做限制。该方法通过区块链网络中任意节点执行,其中节点可以通过任何具有计算、处理能力的装置、设备、平台、设备集群来实现。更具体地,该方法可以通过节点中的虚拟机执行。

如图3所示,更新状态默克树的方法可以包括以下步骤:步骤31,确定状态默克树中由账户的状态变化导致需要更新的待更新节点;步骤32,根据待更新节点,从状态默克树中提取出一个第一子树和M个第二子树,其中第一子树包含状态默克树的根节点,每个第二子树的根节点为待更新节点,且为第一子树中最底层节点的子节点;步骤33,将M个第二子树分配给N个工作线程,使得N个工作线程至少部分并行地处理所述M个第二子树,得到更新后的各个第二子树;步骤34,至少基于更新后的各个第二子树的根节点的值,更新第一子树,从而得到更新后的状态默克树。以下结合以太坊区块链平台来详细描述以上各个步骤的执行过程,但是上述方法也同样地适用于具有类似功能的其他区块链平台。

在一个可选实施例中,在步骤31之前,首先执行步骤30,执行交易集合中的各条交易,确定各条交易涉及的账户的状态变化。该步骤30例如可以是在打包区块时执行,或在验证新生成区块时执行。

具体地,在一个例子中,在打包生成新区块时执行步骤30。可以理解,区块链网络中的任意节点可以执行区块打包来生成新区块,以力求将自己生成的新区块添加到区块链上。进行区块打包生成新区块的节点又可以称为记账节点。在打包生成新区块时,记账节点会从本地的交易池中选取若干交易,构成交易集合,将该交易集合包含在待生成区块中。此时,执行打包的记账节点需要执行上述交易集合中的各条交易,确定交易引起的账户状态的变化。

在另一例子中,在验证新生成区块时执行步骤30。可以理解,当记账节点生成新区块后,会将该新区块在区块链网络中广播。其他节点会收到该新区块,并对其进行验证。验证新区块的节点又可称为验证节点。为了验证该新区块,验证节点需要从该新区块的交易列表中提取出其中包含的交易构成的交易集合,执行该交易集合中的各条交易,从而确定交易引起的账户状态的变化。

在确定出账户的状态变化的基础上,在步骤31,确定状态默克树中由账户的状态变化导致需要更新的待更新节点。为了描述的直观和简单,下文中将需要更新的待更新节点称为“脏节点”;相应的,不需要更新的节点又可称为干净节点。换而言之,步骤31即用于确定状态默克树中的脏节点。

如前所述,状态默克树中的叶节点用于记录账户的状态数据。因此,确定出账户状态的变化,就可以确定出状态默克树中发生更新的叶节点。此外,由于状态默克树中的节点通过哈希进行连接,子节点的哈希值存储在父节点中,因此,如果一个节点是脏节点,它的哈希值需要更新,那么它的父节点也必然是脏节点。因此,步骤31的确定脏节点的过程可以包括,在状态默克树中,从状态发生变化的账户所对应的叶节点向根节点回溯,将回溯路径上经过的所有节点均确定为待更新的脏节点。

图4示出在一个实施例中确定脏节点的示意图。在图4的示例中,假定账户A1,A2,A3,A4和A5的状态均发生了变化,那么与之对应的叶节点发生更新,这些叶节点用灰色块示出。从这些叶节点向根节点方向遍历,所经过的所有节点均可以确定为脏节点,脏节点也用灰色示出。

在确定出待更新脏节点的基础上,在步骤32,根据这些待更新节点,从状态默克树中提取出一个第一子树和M个第二子树,使得第一子树包含状态默克树的根节点,第二子树的根节点为待更新节点,且为第一子树中最底层节点的子节点。为了描述的直观和简单,下文又将第一子树称为根子树(由于其包含整个状态默克树的根节点),将第二子树称为脏子树。

可以采用多种策略从状态默克树中提取出根子树和多个脏子树。

根据一种实现策略,首先按照一定标准选取根子树(第一子树),然后基于根子树提取得到脏子树(第二子树)。

具体的,在一个实施例中,预先设置根子树的层数LN作为选取根子树的标准。于是,在状态默克树中,将根节点到预定层数LN的节点,作为根子树。如此,确保根子树的层数,或者说深度,满足预设要求。

在另一实施例中,预先设置根子树最底层节点中脏节点的数目N1,作为根子树选取标准。根据这样的策略,在状态默克树中,从根节点开始按照宽度优先的原则逐层遍历,如果当前层中脏节点的数目小于上述预设数目N1,则继续遍历下一层;如果当前层中脏节点的数目大于或等于上述预设数目N1,则停止遍历,提取从根节点到当前层的节点作为根子树。如此,确保根子树中每层脏节点的数目满足预设要求。

在其他实施例中,还可以设置其他标准来选取根子树,例如,其中脏节点的总数目达到一定要求,等等。

在按照以上任一种标准选取出根子树之后,基于根子树提取得到脏子树。具体地,可以获取根子树的最底层节点中的脏节点,作为第一节点集合;再获取第一节点集合中各个节点的子节点中的脏节点,作为第二节点集合;然后,分别将第二节点集合中各节点作为起始节点,将从各个起始节点直到叶节点的子树作为脏子树。如此,可以确保,各个脏子树之间没有交集,并且脏子树的根节点是根子树中最底层节点的子节点。

下面延续图4的例子,描述基于图4的状态默克树中的脏节点确定根子树和脏子树的过程。假定在一个例子中,预设的根子树最底层节点中脏节点数目阈值N1=3。那么从图4的根节点开始,逐层遍历。第二层L1中脏节点数目为2,低于上述阈值N1,继续到下一层;第三层L2中脏节点数目为3,达到了上述阈值N1,由此,可以将根节点到L2层的节点作为根子树(第一子树),如图5所示。

现在结合图5进行描述。在确定出根子树后,开始提取脏子树。可以看到,根子树的最底层节点中有3个脏节点(这3个脏节点构成前述的第一节点集合),这3个脏节点共有6个子节点,这6个子节点中有4个脏节点(这4个脏节点构成前述的第二节点集合)。于是,分别以这4个脏节点为起始节点(即脏子树的根节点),将从起始节点直到叶节点的子树作为脏子树,从而得到4个脏子树。

通过以上方式,先确定出根子树,再基于根子树底层节点的子节点中的脏节点,得到脏子树,从而将整个状态默克树划分为根子树、脏子树和其他干净的子树。

可以看到,根子树通过其最底层节点与脏子树关联。根据另一种实现策略,也可以首先按照一定选取标准选取脏子树,进而得到根子树;或者根据一定划分标准,在某一层节点处进行划分,从而分别得到根子树和脏子树。

具体地,在一个实施例中,预设另一脏节点数目阈值N2。在状态默克树中,从根节点开始按照宽度优先逐层遍历,如果当前层中脏节点的数目小于上述阈值N2,则继续遍历;如果大于或等于该阈值N2,则将当前层中的各个脏节点作为起始节点,获取从起始节点直到叶节点的子树作为脏子树;另外,提取从根节点到当前层的上一层的节点作为根子树。根据这样的策略,可以确保得到的脏子树的数目大于或等于N2。

仍然结合图4的状态默克树进行描述。在一个例子中,假定预设的脏节点数目阈值N2=4。从图4的根节点开始,逐层遍历。第一层L0、第二层L1和第三层L2中脏节点数目均达不到该阈值N2,继续到下一层;到第四层L3,脏节点数目为4,达到了上述阈值N2,于是,将该层中的4个脏节点分别作为起始节点(即脏子树的根节点),将从起始节点直到叶节点的子树作为脏子树,从而得到4个脏子树。另外,将该层的上一层,即L2层,到整个默克树根节点的节点作为根子树。于是,同样得到图5所示的根子树和脏子树。

尽管得到同样的子树,但是采用的策略并不相同。事实上,对于一个状态默克树,采用不同策略有可能得到不同的根子树和脏子树分布。例如,如果将N2也设定为3,那么根子树将只包含L0到L1层的节点,L2层中的脏节点则作为脏子树的根节点,得到3个脏子树。

不管采用何种策略,最后得到的根子树是从状态默克树的根节点开始到一定深度的子树,而脏子树的根节点则为根子树最底层节点的子节点,且为脏节点。如此可以确保,各个脏子树的根节点位于同一层级之中,各个脏子树之间两两互斥,没有交集,因此,可以独立地进行更新计算。

因此,对于以上确定出的根子树和脏子树,在步骤33,将各个脏子树分配给多个工作线程,使得各个工作线程并行处理脏子树,对其进行更新。

需要理解,此处的工作线程可以是与前述执行步骤31-32的线程不同的线程。在一个实施例中,通过主线程执行步骤31-32,在确定出多个脏子树后,将该多个脏子树分配给多个工作线程并行进行更新处理。

一般而言,状态默克树通常具有比较均衡的树结构,即各个叶节点离根节点的层数距离不会相差太大。由于各个脏子树的根节点位于同一层级之中,因此,各个脏子树的深度也基本相当,因此,更新各个脏子树的计算量也相当,这进一步有利于各个脏子树的并行更新。

为了描述的清楚和方便,假定步骤32得到的脏子树的数目为M,可用的工作线程的数目为N。

在一个例子中,脏子树的数目M小于或等于可用的工作线程数目N。此时,可以将各个脏子树依次分配给不同的工作线程。于是,M个脏子树各自在不同工作线程中完全并行地进行更新处理。更新处理的过程可以是,从脏子树的叶节点开始,逐层向上重新计算脏节点的哈希,直到脏子树的根节点,从而实现脏子树的更新。

在一个例子中,脏子树的数目M大于可用的工作线程数目N。此时,可以采取取模的方式来分配脏子树。具体的,可以分别对M个脏子树进行编号,例如编号为T(0)到T(M-1);另外,对N个工作线程也进行编号,例如编号为W(0)到W(N-1)。对于M个脏子树中任意的子树i,确定其对应的编号对N取模的结果i mod N,将其分配给编号为该取模结果的工作线程WT(imod N)。

例如,假定有5个工作线程,9个脏子树。则将编号为1和6的脏子树分配到工作线程1,将编号为2和7的脏子树分配到工作线程2,等等。在这样的情况下,有可能一个工作线程分配获得多个脏子树,那么该工作线程依次对分配到的脏子树进行更新处理。对于全部M个脏子树而言,由于分布在N个工作线程中,因此这M个脏子树可以实现部分并行处理。

在一个实施例中,也可以不对M与N的大小关系进行判断,不管其关系如何,均采用取模的方式来分配脏子树。

实践中,可以通过调整子树选取标准中的预设阈值,使得得到的脏子树的数目M与可用工作进程N的大小相当,从而提高脏子树更新的并行度。

在各个工作进程分别对各个脏子树进行更新后,可以将各个脏子树更新后的根哈希提供给主线程。于是,在步骤34,主线程至少基于更新后的各个根节点的哈希值,更新根子树,从而得到更新后的整个状态默克树。

可以理解,由于脏子树的根节点是根子树最底层节点的子节点,因此,基于各个脏子树更新后的根哈希,以及相应的干净节点的哈希值,可以更新根子树中的最底层节点,进而向上逐层递归,更新更上层脏节点的哈希值,直到根节点。此时,根子树也得到了更新。更新后的根子树、更新后的脏子树以及不需更新的干净子树,共同构成整个更新后的状态默克树。

如前所述,更新状态默克树可以发生在打包生成新区块时,或验证新区块时。在生成新区块的情况下,在得到更新的状态默克树之后,将之前选定的交易集合打包到区块中,并将更新后的状态默克树的根哈希记录到区块中,即记录到图1的状态根中。在验证新区块的情况下,在得到更新的状态默克树之后,将更新后的状态默克树的根节点的哈希值与待验证区块的状态根的值进行比较,两者一致则验证通过。

实践中,对于每次状态默克树的更新,可以仅记录更新的节点的相关数据,采用链接或指针的方式,将其与保持不变的节点数据结合在一起。

通过以上过程可以看到,在需要更新状态默克树时,根据本说明书的实施例,将状态默克树中需要更新的部分划分为位于上层的根子树,以及根子树以下多个相互独立的脏子树;然后利用多个工作线程并行对多个脏子树进行更新处理;最后基于各个工作线程对脏子树的更新结果,更新根子树,从而更新整个状态默克树。相比于传统的从叶节点逐层向上串行进行更新处理的方式,并行处理多个脏子树再进行汇总的方式可以显著提高状态默克树的更新效率,进而提高整个区块链网络的系统性能。

根据另一方面的实施例,提供了一种更新状态默克树的装置,所述状态默克树用于存储区块链网络中账户的状态,该装置部署在区块链网络中任意节点中,该节点可以体现为任何具有计算、处理能力的设备、平台或设备集群。图6示出根据一个实施例的状态默克树的更新装置的示意性框图。如图6所示,该更新装置600包括:

节点确定单元61,配置为确定所述状态默克树中由所述账户的状态变化导致需要更新的待更新节点;

子树提取单元62,配置为根据所述待更新节点,从所述状态默克树中提取出一个第一子树和M个第二子树,所述第一子树包含所述状态默克树的根节点,所述M个第二子树两两之间没有交集,每个所述第二子树的根节点为待更新节点,且为所述第一子树中最底层节点的子节点;其中M为大于1的整数;

并行处理单元63,配置为将所述M个第二子树分配给N个工作线程,使得所述N个工作线程至少部分并行地处理所述M个第二子树,得到更新后的各个第二子树;其中N为大于1的整数;

综合更新单元64,配置为至少基于所述更新后的各个第二子树的根节点的哈希值,更新所述第一子树,从而得到更新后的状态默克树。

在一个实施例中,装置600还包括账户状态确定单元60,配置为执行交易集合中的各条交易,确定所述各条交易涉及的账户的状态变化。

具体的,在一个实施例中,上述交易集合可以为从本地交易池中选定的多条交易构成的集合。在这样的情况下,装置600还包括区块生成单元(未示出),配置为,在得到更新后的状态默克树之后,将所述交易集合打包到待生成的第一区块中,并将所述更新后的状态默克树的根节点的哈希值记录到所述第一区块中。

在另一实施例中,上述交易集合为待验证区块中包含的交易构成的集合。在这样的情况下,装置600还包括区块验证单元(未示出),配置为,在得到更新后的状态默克树之后,将所述更新后的状态默克树的根节点的哈希值与所述待验证区块中记录的状态根的值进行比较,以验证所述待验证区块。

根据一种实施方式,所述节点确定单元61配置为:在所述状态默克树中,从状态发生变化的各个账户所对应的各个叶节点向根节点回溯,将回溯路径上经过的所有节点确定为所述待更新节点。

在一个实施例中,所述子树提取单元62配置为:在所述状态默克树中,提取从根节点到预定层数的节点,作为所述第一子树。

在另一实施例中,所述子树提取单元62配置为:在所述状态默克树中,从根节点开始按照宽度优先逐层遍历,如果当前层中待更新节点的数目大于或等于第一预设阈值,则提取从根节点到当前层的节点作为所述第一子树。

进一步的,在一个实施例中,所述子树提取单元62还配置为:

获取所述第一子树的最底层节点中的待更新节点,作为第一节点集合;

获取第一节点集合中各个节点的子节点中的待更新节点,作为第二节点集合;

分别将第二节点集合中各节点作为起始节点,获取从各个起始节点直到叶节点的子树作为所述M个第二子树。

根据另一种实施方式,所述子树提取单元62配置为:

在所述状态默克树中,从根节点开始按照宽度优先逐层遍历,如果当前层中待更新节点的数目大于或等于第二预设阈值,则提取从根节点到当前层的上一层的节点作为所述第一子树,并将当前层中各个待更新节点作为起始节点,获取从各个起始节点直到叶节点的子树作为所述M个第二子树。

根据一个实施例,所述并行处理单元63配置为:

分别对所述M个第二子树和所述N个工作线程进行编号,使得各个第二子树具有对应的第一编号,各个工作线程具有对应的第二编号;

对于所述M个第二子树中任意的第二子树,确定其对应的第一编号对N取模的结果,将其分配给第二编号为该取模结果的工作线程。

根据另一方面的实施例,还提供一种计算机可读存储介质,其上存储有计算机程序,当所述计算机程序在计算机中执行时,令计算机执行结合图3所描述的方法。

根据再一方面的实施例,还提供一种计算设备,包括存储器和处理器,所述存储器中存储有可执行代码,所述处理器执行所述可执行代码时,实现结合图3所述的方法。

本领域技术人员应该可以意识到,在上述一个或多个示例中,本发明所描述的功能可以用硬件、软件、固件或它们的任意组合来实现。当使用软件实现时,可以将这些功能存储在计算机可读介质中或者作为计算机可读介质上的一个或多个指令或代码进行传输。

以上所述的具体实施方式,对本发明的目的、技术方案和有益效果进行了进一步详细说明,所应理解的是,以上所述仅为本发明的具体实施方式而已,并不用于限定本发明的保护范围,凡在本发明的技术方案的基础之上,所做的任何修改、等同替换、改进等,均应包括在本发明的保护范围之内。

去获取专利,查看全文>

相似文献

  • 专利
  • 中文文献
  • 外文文献
获取专利

客服邮箱:kefu@zhangqiaokeyan.com

京公网安备:11010802029741号 ICP备案号:京ICP备15016152号-6 六维联合信息科技 (北京) 有限公司©版权所有
  • 客服微信

  • 服务号