github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/core/mpt/doc.go (about) 1 /* 2 Package mpt implements MPT (Merkle-Patricia Trie). 3 4 An MPT stores key-value pairs and is a trie over 16-symbol alphabet. https://en.wikipedia.org/wiki/Trie 5 A trie is a tree where values are stored in leafs and keys are paths from the root to the leaf node. 6 An MPT consists of 4 types of nodes: 7 - Leaf node only contains a value. 8 - Extension node contains both a key and a value. 9 - Branch node contains 2 or more children. 10 - Hash node is a compressed node and only contains the actual node's hash. 11 The actual node must be retrieved from the storage or over the network. 12 13 As an example here is a trie containing 3 pairs: 14 - 0x1201 -> val1 15 - 0x1203 -> val2 16 - 0x1224 -> val3 17 - 0x12 -> val4 18 19 ExtensionNode(0x0102), Next 20 _______________________| 21 | 22 BranchNode [0, 1, 2, ...], Last -> Leaf(val4) 23 | | 24 | ExtensionNode [0x04], Next -> Leaf(val3) 25 | 26 BranchNode [0, 1, 2, 3, ...], Last -> HashNode(nil) 27 | | 28 | Leaf(val2) 29 | 30 Leaf(val1) 31 32 There are 3 invariants that this implementation has: 33 - Branch node cannot have <= 1 children 34 - Extension node cannot have a zero-length key 35 - Extension node cannot have another Extension node in its next field 36 37 Thanks to these restrictions, there is a single root hash for every set of key-value pairs 38 irregardless of the order they were added/removed in. 39 The actual trie structure can vary because of node -> HashNode compressing. 40 41 There is also one optimization which cost us almost nothing in terms of complexity but is quite beneficial: 42 When we perform get/put/delete on a specific path, every Hash node which was retrieved from the storage is 43 replaced by its uncompressed form, so that subsequent hits of this don't need to access the storage. 44 */ 45 package mpt