首页 > 其他分享 >区块链交易并发: DAG 执行引擎

区块链交易并发: DAG 执行引擎

时间:2024-11-15 19:45:30浏览次数:3  
标签:DAG Level 并行执行 交易 并发 区块 执行 节点

早期的区块链系统,其执行引擎是一个串行执行模型,这种模型虽能保证执行的正确性,但却是区块链性能的一个核心瓶颈之一。天玄链中,通过识别交易中的状态依赖,构建交易依赖图来对执行引擎进行并行化,从而提升交易执行速度,解决该瓶颈。

通用 DAG 分析器

一个无环的有向图称做有向无环图(Directed Acyclic Graph),简称 DAG 图。在一批交易中,可以通过一定方法识别出每笔交易需要占用的互斥资源,再根据交易在 Event 中的顺序及互斥资源的占用关系构造出一个交易依赖 DAG 图,如下图所示,凡是同一 Level (无被依赖的前序任务) 的交易均可以并行执行。如下图所示,基于左图的原始交易列表的顺序进行拓扑排序后,可以得到下图的交易 DAG 。

图1. 交易DAG

图1. 交易DAG

通用 DAG 分析器具体案例

上面两个表格中,我们假设有四笔交易,交易发起的先后顺序如图中序号所示

交易1:用户B转账给用户A 20元钱

交易2:用户C转账给用户D 20元钱

交易3:用户A转账给用户C 15元钱

交易4:用户D转账给用户A 10元钱

各个用户账户的初始余额分别是 10 ,20 , 30 , 40

假设,这四笔交易串行执行,也就是按照交易发起的顺序按序执行,得到的最终余额是25 , 0 ,25, 50。

这个时候,如果我们在不构建任何依赖的前提下,去并行执行这四笔交易。会发生什么呢。并行执行意味着这四笔交易实际执行的物理时间是完全不定的。很可能,交易3是在交易1之前执行完成。

那么我们看看在这种情况下,会发生什么

1. 很明显,如果在交易1都没有完成的情况下,交易3发生了,会导致A用户的账户里不存在足够的余额用于支撑这笔交易,也就是会触发交易1执行失败。

然后,我们会看到,四笔交易都完成后的最终状态和串行执行时的最终状态完全不一致了。

    在系统代码层面,要如何去构建这个 DAG 依赖图呢?我们可以看到,tx 1 和 tx 3 之间之所以存在并行冲突,是因为他们俩都涉及到同一个资源的修改,也就是用户A的账户余额,tx1会用户A的账户余额进行+20的操作,而tx3会对用户A的余额进行-15的操作。所以,如果我们在构建交易的时候将涉及到的资源做好标识,就可以有效的按照资源冲突,去构建DAG图谱了。

DAG核心结构

图2. 核心结构

 

  1. LevelDAG:会根据输入的可执行交易列表 Txs ,最大可并行执行层级(maxParallelLevel)以及最大层级深度(maxLevelDeep),生成可并行执行 ExecuteRootLevel-0)。
  2. ExecuteRoot:可并行执行根节点,该数据结构主要包含可并行执行的节点 (List\) 列表。换言之,并行执行器会并行执行 ExecuteRoot 所对应的可执行节点 (List\) 集合。然后在依据当前 Level 的执行状况,主动触发下一 Level 层级所对应的可执行节点(List\)列表。
  3. Level:当前层级数据结构抽象,主要用于控制最大可并行执行层级(maxParallelLevel),该参数可以这样理解,如当 maxParallelLevel 为 1L 时,即表明 当前执行 Level 必须要等待 Level 1 的所有执行可执行节点执行完成,才可以继续执行。
  4. ExecuteState:执行状态抽象,对应 DAG 中的状态。

通用 DAG 执行引擎

该通用执行引擎的设计目的就是根据 2.1 中通用 DAG 分析器所生成的 ExecuteRoot ,以固定的线程任务,最大并行度地执行交易,根据 LevelDAG 生成的 ExecuteRoot ,并获取 ExecuteRoot 可并行执行节点列表 parallelExecuteNodes,然后遍历该列表节点(ExecuteNode),将执行任务提交给线程池。

线程池会对 ExecuteNode 执行逻辑,具体流程如下:

  1. 先判断节点所在的 Level 的前一个 Level 是否执行完成,如果没有执行完成则加入待重试队列,交由待重试 reactor 线程后续轮循执行。否则,说明当前节点可以执行,则执行相应的交易方法(即可以是以太坊的智能合约交易,也可以是 Java 的智能合约)。

  2. 前置依赖节点执行完成,执行当前 Level 节点。

  3. 当前 Level 每个节点执行完毕。将当前 ExecuteNode 所对应 Level 的待完成执行数减 1(该标志为步骤 1)中判定前置节点是否执行完成).

  4. 遍历当前 ExecuteNode 所对应的被依赖节点,并对被依赖节点执行移除前置依赖。若此时被依赖节点依赖关系节点数量为 0 ,则对该节点执行步骤 1)。如此递归,直到所有的节点被执行完成。

标签:DAG,Level,并行执行,交易,并发,区块,执行,节点
From: https://blog.csdn.net/TianXuan_Chain/article/details/143806252

相关文章

  • CSAPP 并发编程
    frompixiv前置知识进程逻辑控制流(简称逻辑流)CSAPPP508:一系列的程序计数器PC的值唯一地对应于包含在程序的可执目标文件中的指令或包含在运行时动态链接到程序的共享对象指令。这个PC值的序列叫逻辑控制流一个逻辑流的执行在时间上与另一个流重叠,称为并发流,这两个流被......
  • Python并发编程入门:使用concurrent.futures与asyncio
    Python并发编程入门:使用concurrent.futures与asyncio在现代应用中,并发编程已成为一种提升性能和效率的重要手段。Python提供了多种实现并发的方式,尤其是concurrent.futures和asyncio,分别适用于不同的并发场景。本文将带你深入了解这两种并发编程方式,帮助你轻松上手并......
  • Shell并发执行
    在Shell脚本中,实现并发执行可以显著提高处理效率,特别是在处理大量任务或需要同时执行多个命令时。以下是一些常见的方法来实现Shell并发执行:1.使用&符号通过在命令末尾添加&符号,可以将命令放到后台运行,从而实现并发执行#!/bin/bashcommand1&command2&这种方法简单易用,......
  • Rust 如何处理高并发场景?(Rust高并发、Rust并发问题)(Rust Arc、Rust Mutex、Rust RwLock
    Rust如何处理高并发场景Rust的设计原则注重内存安全与并发的平衡,在提供高性能的同时,确保程序的安全性。在并发编程中,Rust提供了多种工具和库,特别是通过所有权、线程安全的类型、异步编程模型和并发原语等方式,解决了高并发场景中的一些难题。1.所有权系统与并发的......
  • Java面试之多线程&并发篇(3)
    前言本来想着给自己放松一下,刷刷博客,突然被几道面试题难倒!SynchronizedMap和ConcurrentHashMap有什么区别?什么是线程安全?Thread类中的yield方法有什么作用?Java线程池中submit()和execute()方法有什么区别?似乎有点模糊了,那就大概看一下面试题吧。好记性不如烂键盘***12......
  • Java面试之多线程&并发篇(3)
    前言本来想着给自己放松一下,刷刷博客,突然被几道面试题难倒!SynchronizedMap和ConcurrentHashMap有什么区别?什么是线程安全?Thread类中的yield方法有什么作用?Java线程池中submit()和execute()方法有什么区别?似乎有点模糊了,那就大概看一下面试题吧。好记性不如烂键盘***12万字的j......
  • HTML区块方面的细节以及表单的使用
    一.HTML中区块元素和内联元素的区别1.HTML区块元素大多数HTML元素被定义为块级元素或内联元素。块级元素在浏览器显示时,通常会以新行来开始(和结束)。(即独占一行)实例:<h1>,<p>,<ul>,<table>2.HTML内联元素内联元素在显示时通常不会以新行开始。实例:<b>,<td>,......
  • 区块反转c++
    代码#include<iostream>#include<vector>usingnamespacestd;structnode{  intdata,next;}A[100001];vector<int>L,ans,E[100001];ints,n,a,t,k,mark,cnt,c;intmain(){  cin>>s>>n>>k;  for(......
  • 【MYSQL】InoDB引擎以及MVCC多版本并发控制【详解】
    一、逻辑存储架构        一个表空间对应的一个ibd文件,里面有许多段,其中包括数据段和索引段还有回滚段,在数据存储模型中的B+树中,叶子节点就是数据段进行存储的,非叶子节点就是索引段进行存储的,回滚段里存储了undolog日志。然后里面还分为区->页->行二、架构......
  • vite将工具函数js打包为npm包并发布
    创建vite项目,将vue依赖清除(因为是纯函数js)npmcreatevitepackage.json中vue的依赖都删掉,把src、public等目录都删掉;package.json文件如下{ "name":"tool",//npm包名 "private":false, "version":"0.0.0", "type":"modul......