Показать сообщение отдельно
  #1 (permalink)  
Старый 09.06.2023, 07:17
Аватар для webgraph
Профессор
Отправить личное сообщение для webgraph Посмотреть профиль Найти все сообщения от webgraph
 
Регистрация: 14.11.2014
Сообщений: 186

Как сделать дерево Modified Merkle Patricia Trie?
У MPT (Merkle Patricia Trie) — есть 3 типа узлов:

  • Branch Node — для ветвления, содержит от 1 до 16 ссылок на другие узлы, а также может содержать значение
  • Extension Node — хранит часть пути, общую для нескольких дочерних узлов, содержит ссылку на Branch Node, который лежит далее
  • Leaf Node — содержит часть пусти и хранимое значение, является конечным в цепочке.




Что мне не понятно — так это то, когда должен создаваться Extension Node или Leaf Node?


Если читать записанную структуру, то всё выглядит понятно:
/*
 *

    Допустим нам надо получить значение какого-то ключа, хеш (путь) которого равен 
    aec952b24ff4d98ea50564c44c2af448a3647bf5dd89da81a801e154fd8180ff.

    Что мы делаем:

    1. Сначала переходим в 10 узел (первый полубайт/ниббл [a] хеша)
    2. Потом идём в 14 узел (второй ниббл [e] хеша)
    3. Потом идём в 12 узел (третий ниббл [c] хеша)
    4. Потом идём в 9 узел (четвёртый ниббл [9] хеша)
    5. Потом приходим в конечный узел 52b2...80ff (оставшаяся часть хеша) где и лежит значение нашего ключа.

 *
 */

    const MerklePatriciaTrie = {
        "type": "branch",
        "children": [
            {}, {}, {}, {}, {}, {}, {}, {}, {},

            // 10-ый узел первого уровня
            {
                "type": "branch",
                "children": [
                    {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},

                    // 14-ый узел второго уровня
                    {
                        "type": "branch",
                        "children": [
                            {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},

                            // 12-ый узел третьего уровня
                            {
                                "type": "branch",
                                "children": [
                                    {}, {}, {}, {}, {}, {}, {}, {},

                                    // 9-ый узел четвёртого уровня
                                    {
                                        "type": "leaf",
                                        "partPath": "52b24ff4d98ea50564c44c2af448a3647bf5dd89da81a801e154fd8180ff",
                                        "value": {
                                            "name": "Patricia Trie"
                                        }
                                    },
                                    {}, {}, {}, {}, {}, {}, {}, {}
                                ]
                            },
                            {}, {}, {}, {}, {}
                        ]
                    },
                    {}, {}, {}
                ]
            },
            {}, {}, {}, {}, {}, {}, {}
        ]
    };


Но если бы у нас был ещё и Extension Node где-то между начальной и конечной точкой, то, возможно это должно выглядеть так?

//a e c952b24ff 4 d98ea50564c44c2af448a3647bf5dd89da81a801e154fd8180ff
    const MPTWithExtension = {
        "type": "branch",
        "children": [
            {}, {}, {}, {}, {}, {}, {}, {}, {},

            // 10-ый узел первого уровня
            {
                "type": "branch",
                "children": [
                    {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},

                    // ******************* 14-ый  EXTENSION узел второго уровня ********************
                    /*
                        То, что мне точно известно — это то, что Extension Node содержит
                        только ссылку на Branch Node.
                        Что касается выражения "partPath" — это только мои догадки...  Не знаю
                        верно ли понимаю эту часть дерева.

                        Понимаю, что Extension Node используется оптимизации — т.е. вместо хранения 16 узлов
                        - хранится только одна ссылка на Branch Node. Именно поэтому у меня складывается мнение,
                        что Extension Node должен содержать какую часть пути (хеша). Если это не так, то прошу
                        поправить меня и объяснить как правильно понимать это.
                     */
                    {
                        "type": "extension",
                        "partPath": "c952b24ff",
                        "nextNode": [
                            {}, {}, {},

                            // 4-ый узел третьего уровня
                            {
                                "type": "leaf",
                                "partPath": "d98ea50564c44c2af448a3647bf5dd89da81a801e154fd8180ff",
                                "value": {
                                    "name": "Patricia Trie"
                                }
                            },
                            {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}
                        ]
                    },
                    {}, {}, {}
                ]
            },
            {}, {}, {}, {}, {}, {}, {}
        ]
    };

Так вот. Как это устроено в целом понятно.

Не понятно как это по итогу записывается? Ну, т.е. по какому принципу создаётся Leaf или Extension узел? И как вообще прокладывается и создаётся этот "ПУТЬ"?

Каким образом функция вычисляет количество вложенных уровней и вообще делает ли она это? Или как это устроено?

Можете показать функцию, которая бы добавляла в дерево новые значения на примере хешей (путей), чьё начало имеет одинаковые нибблы?

Ответить с цитированием