当前位置: 首页 > news >正文

Merkle Patricia Tree

参考文献:

  1. Merkle Tree & Hash-based SIG
  2. Merkle Tree 实现
  3. 以太坊 Merkle Patricia Tree 全解析
  4. Merkle Patricia Tree (梅克尔帕特里夏树) 详解

文章目录

  • MPT 结构
  • 基本操作
    • Get
    • Insert
    • Delete
  • 其他

MPT 结构

Merkle Patricia Tree 是以太坊的关键算法之一。它是一种 16 进制的前缀树(key 编码在 Path 中),具有三种节点:

  1. Branch
    • 具有至少 2 个孩子,至多 16 个孩子
    • 具有以该路径结束(key)的对应 value
    • 附带字段 nodeFlag,包括
      • hash, 本节点的 Hash 值
      • gen, 诞生标记,最近一次被写入/修改的时间
      • dirty,节点是否被修改,若是则 hash 置空以更新
  2. Leaf
    • 和 Branch 类似,除了把 children 换成 key
    • 这个 key 用于处理一段后缀不存在相同前缀其他节点的情况
  3. Extension
    • 与 Leaf 相同,除了把 value 替换为 ptr/idx
    • 这个 ptr/idx 用于持久化存储 MPT 时的检索

以太坊中 Leaf 和 Extension 共享定义,为了在持久化存储中做区分,需要将 Hex 编码替换为 Hex-Prefix 编码

  • 如果 Extension 的 key 为偶数长度 Hex 编码,那么在最前面补 0x00
  • 如果 Extension 的 key 为奇数长度 Hex 编码,那么在最前面补 0x1-
  • 如果 Leaf 的 key 为偶数长度 Hex 编码,那么在最前面补 0x20
  • 如果 Leaf 的 key 为奇数长度 Hex 编码,那么在最前面补 0x3-
  • 最终的 prefix || key 是偶数长度的 Hex 编码

MPT 的整体结构如下:

  1. 树根是一个 Extension 节点,它的 ptr/idx 是其 Branch(或者 Leaf,如果是树桩)子节点的 Hash 值
  2. Branch 节点的 children 存储 16 个孩子各自的 Hash 值
  3. Branch 节点的 children 可以是 Leaf 或者 Extension 节点
  4. Extension 节点的 ptr/idx 是其子节点(branch 或者 leaf)的 Hash 值
  5. 如果该路径是多个 key 的前缀,那么创建 Extersion 以及 Branch
  6. 如果该路径只是单个 key 的前缀,那么创建 Leaf

换句话说,extension 的作用是存储 branch 或 leaf 的 Hash 值(也是索引),branch 的作用是存储最少 2 个、最多 16 个子树的 Hash 值(也是索引),通常 leaf 的父节点是 branch(除非只有一个 extension 作为树桩的根)

在这里插入图片描述

基本操作

Get

假设需要查找 inp_key 的节点,

  1. 当前是 leaf 节点,判断它的 path || key 是否等于 inp_key,输出它的 value 或者 false
  2. 当前是 extension 节点,判断它的 path || key 是否是 inp_key 的前缀,决定是否递归检索 ptr/idx 指向的子节点,或者输出 false
  3. 当前是 branch 节点,如果 path 等于 inp_key,那么输出它的 value
  4. 当前是 branch 节点,如果 pathinp_key 的前缀,那么递归检索下一个 hex 所对应的 children 节点(leaf, extension, empty)

Insert

假设需要插入 inp_key 的节点,

  1. 利用 Get 方法,获取 inp_key 所能匹配的最长前缀节点
  2. 如果它是 leaf 节点,判断 path || key 是否等于 inp_key
    1. 相等,那么更新它的 value
    2. 否则,新建一个 extension 节点和 branch 节点,前者的 key 是最长的公共前缀,后者的两个 children 分别指向原始的 leaf(或者填入 value 如果是前缀的话)和一个新建的 leaf
  3. 如果它是 extension 节点,过程和 leaf 的相似
  4. 如果它是 branch 节点,
    1. 如果 path 等于 inp_key,那么更新它的 value
    2. 如果 pathinp_key 的前缀,那么将对应的 children 指向一个新建的 leaf
  5. 最后,从下向上重建 Merkle Tree

Delete

假设需要删除 inp_key 的(单个)节点,

  1. 利用 Get 方法,获取 inp_key 所能匹配的最长前缀节点
  2. 如果它是 leaf 节点,判断 path || key 是否等于 inp_key
    1. 相等,那么删除它,并判断它的 branch 父节点是否仍具有至少 2 个孩子(包括它的 value 视为一个孩子),作相应的合并调整
    2. 否则,不存在 inp_key 节点,返回 false
  3. 如果它是 extension 节点,那么
    1. 如果 path 等于 inp_key,这是一种非法操作(删除整个子树?)
    2. 如果 path || key 不等于 inp_key,那么返回 false
    3. 不会发生 path || keyinp_key 前缀的情况,这一定会匹配到 extension 的孩子
  4. 如果它是 branch 节点,
    1. 如果 path 等于 inp_key,那么删除 value,但是不要递归删除它的孩子(这个 branch 存储的完整 key 是其他 key 的前缀)
    2. 否则,这意味着不存在 inp_key 节点(不然最长前缀节点不会是 branch 而应该是 extension 或 leaf),返回 false
  5. 最后,从下向上重建 Merkle Tree

其他

如果要求 {key: value} 具有相同长度的键,那么 branch 节点可以移除其 value 域(此时不存在某路径是其他路径的前缀),相应的 Get、Insert、Delete 可以被适当简化。

每个节点都是变长的连续数据块(均包含 keyvalue 域之一),节点的引用是 Hash 值。在内存中,可以利用 std::map 来管理;在磁盘中,如果树很大(无法一次性加载到内存)则使用数据库来管理。

http://www.dtcms.com/a/391860.html

相关文章:

  • 2003-2017年各地级市环境相关指标数据
  • 【开题答辩全过程】以 基于JAVA的视频分享管理系统为例,包含答辩的问题和答案
  • claude-code-和-codex-和-cursor-uniapp前端开发实测
  • 阿里新发布|Qwen3-Next-80B-A3B :MoE 架构破解大模型效率难题,vLLM 落地实测
  • 1型糖尿病中的胰岛细胞病变(β细胞与α细胞)
  • 工频干扰消除算法总结参考
  • 6.栈和队列(上)
  • C语言 ——— 数组
  • 卡尔曼Kalman滤波|基础学习(二)
  • 《2511系统分析师第二遍阅读总结2》
  • FramePack
  • 自注意力机制Self-Attention (三)
  • Vue中窗口拉伸效果实现(Vue2版)
  • idea学习日记1:String的构造方法和内存分析
  • MaxMind DB原理与使用详解
  • TC260-《政务大模型应用安全规范》要点总结
  • 大模型学习:使用FastText工具训练词向量
  • 用html5写一个王者荣耀英雄技能,出装计算模拟器
  • ROS2 使用功能包组织Python节点
  • LibreCAD-2.2.1.2+QT5.15.17
  • 4G、5G
  • 向华为学习——解读华为:2025年AI可信数据空间白皮书【附全文阅读】
  • 2.14composition Api
  • LVGL将本地推送至远程空仓库
  • C++——内存管理
  • EasyClick JavaScript 错误处理机制
  • 六应用层-思考题
  • 多实例部署mysql
  • 信创国产化改造(改成人大金仓)
  • 远程修改的烦恼FacePoke和cpolar联手已帮您解决