-
Notifications
You must be signed in to change notification settings - Fork 14
MPT trie
FZQA edited this page Oct 23, 2018
·
3 revisions
StateTrie key-sha3(以太坊账户地址) value-rlp(账户内容信息)
TransactionTrie
ReceiptsTrie
//叶子节点(Leaf) 扩展节点(Extention) 分支节点(Branch)
// MPT-node分为4种类型
type (
fullNode struct { //分支节点 fullNode本身不再需要额外key变量
Children [17]node // Actual trie node data to encode/decode (needs custom encoder)
flags nodeFlag
}
shortNode struct { //shortNode.Val的类型来对应到底是叶子节点(valueNode)还是扩展节点(fullNode)
Key []byte
Val node
//扩展节点,Val指向分支节点或者叶子节点
//叶子节点,Val为rlp编码数据,key为该数据的hash
flags nodeFlag
}
hashNode []byte //fullNode或者shortNode对象的RLP哈希值
valueNode []byte //叶子节点 不带子节点
)
type Trie struct {
db *Database //lecelDB做KV存储
root node //当前根节点
originalRoot common.Hash //启动加载时候的hash,可以从db中恢复出整个trie
// Cache generation values.
// cachegen increases by one with each commit operation.
// new nodes are tagged with the current generation and unloaded
// when their generation is older than than cachegen-cachelimit.
cachegen, cachelimit uint16 // cachegen 缓存生成值,每次Commit会+1
}
RAW原始编码(keybytes encoding):大部分Trie API使用
HEX十六进制编码(节点加入到内存中使用):
1、RAW编码输入的每个byte分为高4位和低4位 (半字节nibble)
2、叶子节点最后面加上0x10表示结束
3、分支节点不附加任何hex值
example:key="bob"=raw-[0x62 0x6f 0x62]----hex-[6 2 6 f 6 2 1 0]
HEX-Prefix编码(compact)(存储到数据库使用格式节约磁盘空间):
1、若输入key结尾为0x10,去掉这个终止符
2、key最前端补一个flag四元组,在flag低2位中,第0位为1代表叶子节点,第1位为1代表奇数长度
3、若输入的key长度为偶数,则flag四元组后再添加一个四元组0x0
4、将原来key压缩,两个byte以高四位低四位合并
example:[6 2 6 f 6 2 1 0]-去掉0x10-[6 2 6 f 6 2]-补flag四元组0010(1代表叶子节点 最后的0代表偶数长度)-偶数再加一个四元组0000-[2 0 6 2 6 f 6 2]-压缩-[0x20 0x62 0x6f 0x62]
序列化:内存——数据库 hex——compact
反序列化:数据库——内存 compact——hex
(可能理解有误)
加载整棵树
func New() trie/trie.go
↓↓↓
func resolveHash() trie/trie.go
↓↓↓