基于联盟链的事件防丢失方法、系统、装置及存储介质转让专利

申请号 : CN202110430469.9

文献号 : CN113157522B

文献日 :

基本信息:

PDF:

法律信息:

相似专利:

发明人 : 黄步添李永健刘强梁逸敏刘振广万志国

申请人 : 杭州云象网络技术有限公司

摘要 :

本发明提出了一种基于联盟链的事件防丢失方法与系统,具体包括:响应于触发网络重启的动作,从EventMap和数据库获取区块编号,其中,EventMap用于记录每个区块中的事件,每个区块包含多个事件,区块与区块编号一一对应;基于区块编号是否为空判断事件是否丢失,基于区块编号的判断结果对联盟链网络的区块进行监听;若为空,则从联盟链网络的最新区块开始监听,否则,从区块编号对应的区块开始监听;将监听到的区块编号存入EventMap和数据库中。本发明解决了重启后事件丢失的问题,使用event监听机制代替之前的轮训机制实时获取链上消息,使用分布式锁解决多后端情况下的event重复触发,并且使用了断点重续与提案执行的幂等性确保event不会丢失。

权利要求 :

1.一种基于联盟链的事件防丢失方法,其特征在于,具体包括:

响应于触发网络重启的动作;

为保证事件监听的幂等性,在执行前去链上查询数据,判断是否已经执行过,若已执行过则不重复执行;

从EventMap和数据库获取区块编号,其中,EventMap用于记录每个区块中的事件,每个区块包含多个事件,区块与区块编号一一对应;

基于区块编号是否为空判断事件是否丢失,基于区块编号的判断结果对联盟链网络的区块进行监听;

若为空,则从联盟链网络的最新区块开始监听,否则,从区块编号对应的区块开始监听;

将监听到的区块编号存入EventMap和数据库中;

若存在多后端多事件,则采用分布式锁保证多个后端有且只有一个后端开启事件监听,如果监听被关闭,多后端中的一个会自动开启监听。

2.根据权利要求1所述的基于联盟链的事件防丢失方法,其特征在于,将监听到的区块编号存入EventMap包括:将区块编号作为EventMap的value,在EventMap获取到区块中事件的txID和区块编号,若没有,则存储区块中事件的txID和区块编号,若有,则删除EventMap中事件的txID和区块编号,其中,事件与交易一一对应,将交易的txID作为EventMap的Key。

3.根据权利要求2所述的基于联盟链的事件防丢失方法,其特征在于,还包括:每次删除事件区块的txID和区块编号后须遍历EventMap,将最小的区块编号存到数据库中。

4.根据权利要求1所述的基于联盟链的事件防丢失方法,其特征在于,还包括过滤掉不合格事件的步骤,其中,不合格事件包括无效交易事件、没有交易的事件和未注册的交易事件中的任意一种;具体为:判断交易是否合格,若合格,则将该事件存储到EventMap;若不合格,则过滤掉该事件。

5.根据权利要求1所述的基于联盟链的事件防丢失方法,其特征在于,所述分布式锁包括延长锁和删除死锁;在任何时间下,延长锁根据锁名和ClientId查询数据库是否有满足第一条件的锁,若有,则更新ValidTime+10秒,其中,第一条件为当前时间>CreatTime+VaildTime‑5秒;在任何时间下,删除死锁根据锁名查询数据库中是否有满足第二条件的锁,若有,则删除,其中,第二条件为当前时间>CreatTime+VaildTime,CreatTime为加锁时间,ValidTime为延长时间。

6.一种基于联盟链的事件防丢失系统,其特征在于,包括数据获取模块、编码判断模块、执行监听模块、编号存储模块和防重复监听模块;

所述数据获取模块,用于响应于触发网络重启的动作,从EventMap和数据库获取区块编号,其中,EventMap用于记录每个区块中的事件,每个区块包含多个事件,区块与区块编号一一对应;

所述编码判断模块,基于区块编号是否为空判断事件是否丢失,基于区块编号的判断结果对联盟链网络的区块进行监听;

所述执行监听模块,被设置为:若为空,则从联盟链网络的最新区块开始监听,否则,从传入的区块开始监听;

所述编号存储模块,用于将监听到的区块编号存入EventMap和数据库中;

所述防重复监听模块,用于防止事件被重复监听,在执行前去链上查询数据,判断是否已经执行过,若已执行过则不重复执行;若存在多后端多事件,则采用分布式锁保证多个后端有且只有一个后端开启事件监听,如果监听被关闭,多后端中的一个会自动开启监听。

7.根据权利要求6所述的基于联盟链的事件防丢失系统,其特征在于,还包括分布式锁执行模块,被设置为:若存在多后端多事件,则采用分布式锁保证多个后端有且只有一个后端开启事件监听;

所述分布式锁包括延长锁和删除死锁;在任何时间下,延长锁根据锁名和ClientId查询数据库是否有满足第一条件的锁,若有,则更新ValidTime+10秒,其中,第一条件为当前时间>CreatTime+VaildTime‑5秒;在任何时间下,删除死锁根据锁名查询数据库中是否有满足第二条件的锁,若有,则删除,其中,第二条件为当前时间>CreatTime+VaildTime,CreatTime为加锁时间,ValidTime为延长时间。

8.一种计算机可读存储介质,所述计算机可读存储介质存储有计算机程序,其特征在于,所述计算机程序被处理器执行时实现如权利要求1至5任意一项所述的方法步骤。

9.一种基于联盟链的事件防丢失装置,包括存储器、处理器以及存储在所述存储器中并可在所述处理器上运行的计算机程序,其特征在于,所述处理器执行所述计算机程序时实现如权利要求1至5任意一项所述的方法步骤。

说明书 :

基于联盟链的事件防丢失方法、系统、装置及存储介质

技术领域

[0001] 本发明涉及区块链技术领域,具体涉及一种基于联盟链的事件防丢失方法、系统、装置及存储介质。

背景技术

[0002] 随着以比特币为代表的数字加密货币体系的问世,区块链技术得到飞速发展,现在已经有许多企业在使用基于Fabric的联盟链网络服务,网络事件监听就是Fabric提供的服务之一。一般而言,事件(Event)是指程序检测到的动作或事件。事件包支持访问Fabric网络上的通道事件。事件客户端可以接收区块事件、过滤块事件、链码事件和交易状态事件。用户单击鼠标按钮是一个事件的示例,程序必须已经实现了某种事件监听器才能监听事件并在事件发生时采取某些操作。在Fabric中,有三种类型的事件监听器来监听事件:块监听器,交易监听器,链码监听器。
[0003] 但是这些事件监听是短暂的,在联盟链中有多个组织的网络下,单个组织因为系统宕机或是服务中断等异常情况,导致事件监听服务停止,重启后监听器就会错过所监听的事件,会遗漏停止期间发生的事件。

发明内容

[0004] 基于背景技术中提出的问题,本发明提出了一种基于联盟链的事件防丢失方法、系统、装置及存储介质。
[0005] 一种基于联盟链的事件防丢失方法,具体包括:
[0006] 响应于触发网络重启的动作,从EventMap和数据库获取区块编号,其中,EventMap用于记录每个区块中的事件,每个区块包含多个事件,区块与区块编号一一对应;
[0007] 基于区块编号是否为空判断事件是否丢失,基于区块编号的判断结果对联盟链网络的区块进行监听;
[0008] 若为空,则从联盟链网络的最新区块开始监听,否则,从传入的区块开始监听;
[0009] 将监听到的区块编号存入EventMap和数据库中。
[0010] 作为一种可实施方式,将监听到的区块编号存入EventMap包括:将区块编号作为EventMap的value,在EventMap获取到区块中事件的txID和区块编号,若没有,则存储区块中事件的txID和区块编号,若有,则删除EventMap中事件的txID和区块编号,其中,事件与交易一一对应,将交易的txID作为EventMap的Key。
[0011] 作为一种可实施方式,还包括:每次删除事件区块的txID和区块编号后须遍历EventMap,将最小的区块编号存到数据库中。
[0012] 作为一种可实施方式,还包括过滤掉不合格事件的步骤,其中,不合格事件包括无效交易事件、没有交易的事件和未注册的交易事件中的任意一种;具体为:判断交易是否合格,若合格,则将该事件存储到EventMap;若不合格,则过滤掉该事件。
[0013] 作为一种可实施方式,还包括以下步骤:若存在多后端多事件,则采用分布式锁保证多个后端有且只有一个后端开启事件监听。
[0014] 作为一种可实施方式,所述分布式锁包括延长锁和删除死锁;在任何时间下,延长锁根据锁名和ClientId查询数据库是否有满足第一条件的锁,若有,则更新ValidTime+10秒,其中,第一条件为当前时间>CreatTime+VaildTime‑5秒;在任何时间下,删除死锁根据锁名查询数据库中是否有满足第二条件的锁,若有,则删除,其中,第二条件为当前时间>CreatTime+VaildTime。
[0015] 一种基于联盟链的事件防丢失系统,包括数据获取模块、编码判断模块、执行监听模块和编号存储模块;
[0016] 所述数据获取模块,用于响应于触发网络重启的动作,从EventMap和数据库获取区块编号,其中,EventMap用于记录每个区块中的事件,每个区块包含多个事件,区块与区块编号一一对应;
[0017] 所述编码判断模块,基于区块编号是否为空判断事件是否丢失,基于区块编号的判断结果对联盟链网络的区块进行监听;
[0018] 所述执行监听模块,被设置为:若为空,则从联盟链网络的最新区块开始监听,否则,从传入的区块开始监听;
[0019] 所述编号存储模块,用于将监听到的区块编号存入EventMap和数据库中。
[0020] 作为一种可实施方式,还包括分布式锁执行模块,被设置为:
[0021] 若存在多后端多事件,则采用分布式锁保证多个后端有且只有一个后端开启事件监听;
[0022] 所述分布式锁包括延长锁和删除死锁;在任何时间下,延长锁根据锁名和ClientId查询数据库是否有满足第一条件的锁,若有,则更新ValidTime+10秒,其中,第一条件为当前时间>CreatTime+VaildTime‑5秒;在任何时间下,删除死锁根据锁名查询数据库中是否有满足第二条件的锁,若有,则删除,其中,第二条件为当前时间>CreatTime+VaildTime。
[0023] 一种计算机可读存储介质,所述计算机可读存储介质存储有计算机程序,其特征在于,所述计算机程序被处理器执行时实现如下的方法步骤:
[0024] 响应于触发网络重启的动作,从EventMap和数据库获取区块编号,其中,EventMap用于记录每个区块中的事件,每个区块包含多个事件,区块与区块编号一一对应;
[0025] 基于区块编号是否为空判断事件是否丢失,基于区块编号的判断结果对联盟链网络的区块进行监听;
[0026] 若为空,则从联盟链网络的最新区块开始监听,否则,从传入的区块开始监听;
[0027] 将监听到的区块编号存入EventMap和数据库中。
[0028] 一种基于联盟链的事件防丢失装置,包括存储器、处理器以及存储在所述存储器中并可在所述处理器上运行的计算机程序,其特征在于,所述处理器执行所述计算机程序时实现如下的方法步骤:
[0029] 响应于触发网络重启的动作,从EventMap和数据库获取区块编号,其中,EventMap用于记录每个区块中的事件,每个区块包含多个事件,区块与区块编号一一对应;
[0030] 基于区块编号是否为空判断事件是否丢失,基于区块编号的判断结果对联盟链网络的区块进行监听;
[0031] 若为空,则从联盟链网络的最新区块开始监听,否则,从传入的区块开始监听;
[0032] 将监听到的区块编号存入EventMap和数据库中。
[0033] 在联盟链中有多个组织的网络下,单个组织因为系统宕机或是服务中断等异常情况,导致事件监听服务停止,重启后会遗漏停止期间发生的事件。本发明提出的一种联盟链网络中事件防丢失方法与系统,解决了重启后事件丢失的问题,使用event监听机制代替之前的轮训机制实时获取链上消息,使用分布式锁解决多后端情况下的event重复触发,并且使用了断点重续与提案执行的幂等性确保event不会丢失。

附图说明

[0034] 为了更清楚地说明本申请实施例的技术方案,下面将对实施例描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本申请的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图。
[0035] 图1为某一具体实施例中事件监听流程图;
[0036] 图2为某一具体实施例中过滤块事件与链码事件监听流程图;
[0037] 图3为某一具体实施例中分布式锁工作流程图。

具体实施方式

[0038] 为使本发明实施例的目的、技术方案和优点更加清楚,下面将结合附图对本发明的技术方案进行清楚、完整地描述,显然,所描述的实施例是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。
[0039] 在本说明书的描述中,参考术语“一实施例”、“一具体实施例”、“一实施例方式”、“例如”的描述意指结合该实施例或示例描述的具体特征、结构或者特点包含于本申请的至少一个实施例或示例中。在本说明书中,对上述术语的示意性表述不一定指的是相同的实施例或示例。而且,描述的具体特征、结构或者特点可以在任何的一个或多个实施例或示例中以合适的方式结合。各实施例中涉及的步骤顺序用于示意性说明本申请的实施,其中的步骤顺序不作限定,可根据需要作适当调整。
[0040] Event包支持访问Fabric网络上的通道事件。事件客户端可以接收区块事件、过滤块事件、链码事件和交易状态事件。
[0041] 事件监听服务使用基本流程包括:
[0042] A.创建事件客户端;
[0043] B.注册事件;
[0044] C.处理事件;
[0045] D.注销事件。
[0046] 在注册链码事件前,必须在对应的链码下通过调用stub.SetEvent(eventName string,payload[]byte)来抛出event,其中注册的事件名要和SetEvent的事件名一致。
[0047] 本发明提出的一种基于联盟链的事件防丢失方法与系统,解决了重启后事件丢失的问题,使用event监听机制代替之前的轮训机制实时获取链上消息,使用分布式锁解决多后端情况下的event重复触发,并且使用了断点重续与提案执行的幂等性确保event不会丢失。
[0048] 如图1所示是本发明某一具体实施例中事件监听流程示意图,流程具体包括:
[0049] (1)当新起联盟链网络时,开启事件监听器,从最新的区块开始监听;
[0050] (2)在监听过程中记录监听到的区块编号存入EventMap和数据库中;
[0051] (3)系统重启时,从数据库获取区块编号,判断区块编号是否为空,是则从最新区块开始监听,否则从传入的区块编号开始监听;
[0052] (4)记录监听到的区块编号存入EventMap和数据库中。
[0053] EventMap:用于存储事件和查找事件的地图,事件对应交易的txID作为EventMap的Key,区块编号作为EventMap的value。
[0054] 在处理链码事件时需要在链码中调用stub.SetEvent方法来设置事件,其内容如下:
[0055] 1.//SetEvent documentation canbe found in interfaces.go
[0056] 2.func(stub*ChaincodeStub)SetEvent(name string,payload[]byte)error{[0057] 3.ifname==""{
[0058] 4.return errors.New("event name can not be nil string")
[0059] 5.}
[0060] 6.stub.chaincodeEvent=&pb.ChaincodeEvent{EventName:name,Payload:payload}
[0061] 7.return nil
[0062] 8.}
[0063] 可以看出该方法的本质是对stub.chaincodeEvent的赋值,在一个交易里调用多次stub.SetEvent方法只有最后一次的调用会生效,由此得出一个交易对应一个事件。基于以上结论,使用txID作为EventMap的Key,区块编号作为EventMap的value,来保证EventMap记录的事件的唯一。
[0064] Fabric提供了创建事件客户端服务的接口,创建事件客户端时要注意ClientOption选项构建:
[0065] 1.func WithBlockEvents()ClientOption
[0066] 2.WithBlockEvents指示要接收的区块事件。注意,调用者必须具有此选项的足够权限。
[0067] 3.func WithBlockNum(from uint64)ClientOption
[0068] 4.WithBlockNum表示用于接收事件的区块编号。只有deliverclient支持次选项。
[0069] 5.func WithSeekType(seek seek.Type)ClientOption
[0070] 6.WithSeekType表示所需的搜索类型,Newest,Oldest或FromBlock,只有deliverclient支持此项。
[0071] 只要配置了接收事件的区块编号和搜索类型为FromBlock,peer节点在拉取区块时就会从指定的区块编号拉取,从而防止错失区块导致事件丢失的发生。
[0072] 在当前条件下,需要考虑如何保证指定的区块编号就是停止监听时最后执行的区块。对此解决方案如下:
[0073] 通过过滤块监听,获取到事件区块的txID和区块编号就到EventMap中查找,如果没有就存储,有就删除;
[0074] 在处理完链码事件后,拿事件区块的txID和区块编号到EventMap中查找,如果没有就存储,有就删除;
[0075] 每次删除都遍历一遍EventMap,将最小的区块编号存到数据库。
[0076] 监听过滤块时,要过滤掉无效交易、没有事件的交易和未注册的交易,如果不过滤EventMap会残留无用的数据,导致数据库的区块无法更新,因为链码事件监听是会自动过滤掉无效交易,并且只会处理注册的事件。如图2所示是过滤块事件与链码事件监听流程示意图。开启新的事件监听时,若事件为过滤块事件时,判断交易是否有效、交易是否存在事件、交易中的事件是否已注册,若全是则将该事件存储到EventMap,若有否则过滤掉该事件;若事件为链码事件时,则正常处理事件,将该事件存储到EventMap中,再存入数据库中。事件实例如下所示:
[0077] 其中:
[0078] 1.type EventInstence struct{
[0079] 2.Client*event.Client//事件客户端
[0080] 3.ClosCCNotify chan bool//关闭事件监听
[0081] 4.RegisterEventMap map[string]bool//记录已注册的链码事件
[0082] 5.EventMap map[string]uint64//记录运行中的事件
[0083] 6.}
[0084] ClosCCNotify用于关闭事件监听;
[0085] RegisterEventMap是记录已注册的链码事件,在监听过滤块时用于筛选事件,避免不用的事件记录到了EventMap;
[0086] EventMap是以txID为key,区块编号为volue,因为一次交易只会触发一个事件,所以交易和事件是一对一的关系,一个事件就会有一个唯一的交易ID。
[0087] 在多后端的情况下,如果每个后端有一个事件监听,可能会出现多个事件监听同时进行的情况,导致大量事件被重复执行,出现数据库数据冗余。此时采用分布式锁的方法来保证多个后端只会有一个后端开启监听,如果监听被关闭,多后端中的一个会自动开启监听。如图3所示是分布式锁工作流程图,在开启事件监听前获取锁,具体包括在数据库中插入一条以锁名为主键的数据,不成功则重复执行这一步,直到加锁成功;在停止事件监听后释放锁,从数据库中删除以锁名为主键的数据。
[0088] 1.type DBLock struct{
[0089] 2.Name string`orm:"column(name);pk"`//锁名
[0090] 3.ClientId string//后端id每个后端对应一个id
[0091] 4.GoId uint64//加锁线程id
[0092] 5.CreateTime int64//加锁时间
[0093] 6.ValidTime int64//延长时间
[0094] 7.}
[0095] 为防止死锁的出现,在加分布式锁时会创建两个协程,一个是延长锁、一个是删除死锁;延长锁每秒都会根据锁名和ClientId查询数据库中有没有满足条件(当前时间>CreatTime+VaildTime‑5秒)的锁,有就更新ValidTime+10秒;删除死锁每秒都会根据锁名查询数据库中有没有满足条件(当前时间>CreatTime+VaildTime)的锁,有就删除。
[0096] 本方案虽然能保证链码事件不会丢失,但不能防止链码事件处理不会重复执行,所以在处理链码事件时要保证处理方法的幂等性,即多次执行处理事件的方法也不会改变最终的结果。可采用的方案是,在执行前去链上查询数据,判断是否已经执行过,若已执行过则不重复执行。
[0097] 本领域技术人员在考虑说明书及实践这里公开的发明后,将容易想到本说明书的其它实施方案。本说明书旨在涵盖本说明书的任何变型、用途或者适应性变化,这些变型、用途或者适应性变化遵循本说明书的一般性原理并包括本说明书未公开的本技术领域中的公知常识或惯用技术手段。说明书和实施例仅被视为示例性的,本说明书的真正范围和精神由权利要求指出。
[0098] 应当理解的是,本说明书并不局限于上面已经描述并在附图中示出的精确结构,并且可以在不脱离其范围进行各种修改和改变。本说明书的范围仅由所附的权利要求来限制。