Method for reading blockchain state data and blockchain node
By constructing a tree-structured world state in blockchain nodes and utilizing location indexes to quickly locate and load data, the problems of read amplification and low efficiency when reading blockchain state data are solved, achieving efficient data reading.
Patent Information
- Application Number
- PCT/CN2024/128753
- Authority / Receiving Office
- WO · WO
- Patent Type
- Applications
- Current Assignee / Owner
- Priority Date
- 2024-07-11
- Filing Date
- 2024-10-31
- Publication Date
- 2026-01-15
AI Technical Summary
Existing technologies suffer from read amplification issues and inefficiency due to multiple leaf node lookups when reading blockchain state data, resulting in slow data loading speeds and an inability to efficiently locate and load state data.
The world state adopts a tree structure, which is built in memory. The leaf nodes contain the location index of the data file in the persistent storage medium. The data is quickly located and loaded by the location index, avoiding reading a large number of files in multiple levels of SST. Only the index file is searched to improve search efficiency.
It enables rapid location and loading of blockchain state data, avoids read amplification issues, and improves data reading efficiency and search speed.
Smart Images

Figure CN2024128753_15012026_PF_FP_ABST
Abstract
Description
A method for reading blockchain state data and a blockchain node
[0001] This application claims priority to Chinese Patent Application No. 2024109334410, filed on July 11, 2024, entitled "A Method for Reading Blockchain State Data and a Blockchain Node", the entire contents of which are incorporated herein by reference. Technical Field
[0002] The embodiments in this specification belong to the field of blockchain technology, and in particular relate to a method for reading blockchain state data and a blockchain node. Background Technology
[0003] Blockchain is a novel application model of computer technologies such as distributed data storage, peer-to-peer transmission, consensus mechanisms, and cryptographic algorithms. In a blockchain system, data blocks are sequentially linked together to form a chain-like data structure, and a distributed ledger is cryptographically guaranteed to be immutable and unforgeable. Due to its decentralized, immutable, and autonomous characteristics, blockchain is receiving increasing attention and application.
[0004] Summary of the Invention
[0005] The purpose of this invention is to provide a method for reading blockchain state data and a blockchain node, including:
[0006] A method for reading blockchain state data is applied to the storage module of a blockchain node. The storage module constructs a tree-structured world state in memory, and the leaf nodes of the tree structure include the position index of the state data within a data file in a persistent storage medium. The method includes:
[0007] The storage module of the blockchain node receives the instruction to look up the state key and searches for the leaf node corresponding to the state key in the tree structure in memory;
[0008] Obtain the location index contained in the leaf node, where the location index points to a location within the data file in the persistent storage medium;
[0009] Load the value of the data file location in the persistent storage medium pointed to by the location index into memory and read the status data therein.
[0010] A blockchain node includes a storage module, which comprises a tree construction module and persistent storage. The persistent storage medium includes an index file and a data file. The storage module also includes a lookup unit and a read unit. The leaf nodes of the tree structure include an index of the position of state data within the data file in the persistent storage medium.
[0011] The tree-building module is used to build the world state of a tree structure in memory;
[0012] The search unit receives an instruction to search for a state key, searches for the leaf node corresponding to the state key in the tree structure in memory, and obtains the location index contained in the leaf node, the location index pointing to the location in the data file in the persistent storage medium;
[0013] The reading unit loads the value of the data file location in the persistent storage medium pointed to by the location index into memory and reads the status data therein.
[0014] In the above embodiments, storing a location index in the leaf node allows for quick location of the leaf node's value within the data file after the leaf node is found. This enables direct loading of the content at the corresponding location in the data file into memory, avoiding the read amplification problem caused by reading and loading large amounts of files from multiple levels of the SST. It also avoids the need for multiple binary search operations within the SST based on the leaf node's key (the hash value of the value) when storing both the leaf node's key and value in the persistent SST file. Furthermore, similarly, if the leaf node to be searched is not present in the memory of the tree-building module, the above embodiments can search only the index file. This allows for loading more index files into memory within a unit of space for searching, thus finding the leaf node faster. Attached Figure Description
[0015] To more clearly illustrate the technical solutions of the embodiments in this specification, the drawings used in the description of the embodiments will be briefly introduced below. Obviously, the drawings described below are only some embodiments recorded in this specification. For those skilled in the art, other drawings can be obtained based on these drawings without creative effort.
[0016] Figure 1 is a schematic diagram of deploying a smart contract in one embodiment;
[0017] Figure 2 is a schematic diagram of calling a smart contract in one embodiment;
[0018] Figure 3 is a schematic diagram of a block storage structure in one embodiment;
[0019] Figure 4 is a schematic diagram of a block storage structure in one embodiment;
[0020] Figure 5 is a schematic diagram of an MPT tree in one embodiment;
[0021] Figure 6 is a schematic diagram of the modules involved in the transaction processing process and the relationship between CPU, memory and disk in one embodiment;
[0022] Figure 7 is a schematic diagram of the modules involved in the transaction processing process and the relationship between CPU, memory and disk in one embodiment;
[0023] Figure 8 is a schematic diagram of the logical relationship of the state database in one embodiment;
[0024] Figure 9 is a flowchart of reading status data in one embodiment;
[0025] Figure 10 is a schematic diagram illustrating the reading of status data in an embodiment using a tree structure;
[0026] Figure 11 is a schematic diagram illustrating the reading of status data in conjunction with a tree structure in one embodiment;
[0027] Figure 12 is a schematic diagram illustrating the reading of status data in an embodiment using a tree structure;
[0028] Figure 13 is a schematic diagram illustrating the reading of status data in one embodiment using a tree structure;
[0029] Figure 14 is a schematic diagram illustrating the reading of status data in one embodiment using a tree structure. Detailed Implementation
[0030] To enable those skilled in the art to better understand the technical solutions in this specification, the technical solutions in the embodiments of this specification will be clearly and completely described below with reference to the accompanying drawings. Obviously, the described embodiments are only some embodiments of this specification, and not all embodiments. Based on the embodiments in this specification, all other embodiments obtained by those skilled in the art without creative effort should fall within the scope of protection of this specification.
[0031] Blockchains are generally classified into three types: public blockchains, private blockchains, and consortium blockchains. In addition, there are various combinations of these types, such as private blockchains + consortium blockchains, consortium blockchains + public blockchains, etc. Public blockchains offer the highest degree of decentralization. Represented by Bitcoin and Ethereum, public blockchains allow participants to read data records on the chain, participate in transactions, and compete for the right to record new blocks. Furthermore, participants (represented by nodes on the blockchain) can freely join and leave the network and perform related operations. Private blockchains, on the other hand, have write permissions controlled by a specific organization or institution, and data read permissions are regulated by that organization. Simply put, a private blockchain can be a weakly centralized system with strictly limited and few participating nodes. This type of blockchain is more suitable for internal use within specific institutions. Consortium blockchains fall between public and private blockchains, achieving "partial decentralization." Each node in a consortium blockchain typically has a corresponding entity or organization; participants join the network through authorization and form a consortium of stakeholders to jointly maintain the operation of the blockchain.
[0032] Whether it's a public, private, or consortium blockchain, besides supporting the transfer of native assets on the blockchain between accounts, such as transferring Bitcoin and Ethereum, it can also provide smart contract functionality. A smart contract on the blockchain is a contract that can be triggered and executed by transactions on the blockchain system. Smart contracts can be defined in the form of code.
[0033] Taking Ethereum as an example, enabling users to create and invoke complex logic within the Ethereum network is the biggest challenge that distinguishes Ethereum from Bitcoin's blockchain technology. At the core of Ethereum as a programmable blockchain is the Ethereum Virtual Machine (EVM), which can be run by every Ethereum node. The EVM is a Turing-complete virtual machine, meaning that various complex logics can be implemented through it. Users publishing and invoking smart contracts in Ethereum run on the EVM. In fact, the virtual machine directly runs virtual machine code (virtual machine bytecode, hereinafter referred to as "bytecode"). Smart contracts deployed on the blockchain can be in the form of bytecode.
[0034] For example, as shown in Figure 1, after Bob sends a transaction containing information about creating a smart contract to the Ethereum network, Node 1's EVM can execute this transaction and generate the corresponding contract instance. In Figure 1, "0x6f8ae93…" represents the address of this contract. The transaction's data field can store bytecode, and the transaction's to field is an empty account. After the nodes reach a consensus through the consensus mechanism, the contract is successfully created, and users can subsequently call this contract.
[0035] After a contract is created, a contract account corresponding to that smart contract is generated on the blockchain, with a specific address. The contract code and account storage are stored in this contract account. The behavior of the smart contract is controlled by the contract code, while the smart contract's account storage preserves the contract's state. In other words, a smart contract enables the creation of a virtual account on the blockchain that contains both contract code and account storage.
[0036] As mentioned earlier, the `data` field of a transaction that creates a smart contract can store the bytecode of that smart contract. Bytecode consists of a series of bytes, with each byte representing an operation. For reasons of development efficiency and readability, developers can choose to write smart contract code in a high-level language instead of directly writing bytecode. The smart contract code written in a high-level language is compiled by a compiler to generate bytecode, which can then be deployed to the blockchain. Ethereum supports many high-level languages, such as Solidity, Serpent, and LLL.
[0037] Taking Solidity as an example, contracts written in it are very similar to classes in object-oriented programming languages. A contract can declare various members, including state variables, functions, function modifiers, events, etc. State variables are values stored in the smart contract's account store and are used to save the contract's state.
[0038] The following is a simple code example 1 of a smart contract written in the Solidity language:
[0039] Furthermore, as shown in Figure 2, still using Ethereum as an example, after Bob sends a transaction containing information about calling a smart contract to the Ethereum network, the EVM of node 1 can execute this transaction and generate the corresponding contract instance. In Figure 2, the `from` field of the transaction is the address of the account initiating the smart contract call, and "0x6f8ae93…" in the `to` field represents the address of the called smart contract. The `data` field of the transaction stores the method and parameters for calling the smart contract. Additionally, it may include a `value` field to represent the value of Ether in the transaction. After calling the smart contract, the value of `storedData` may change. Subsequently, a client can view the current value of `storedData` through a specific blockchain node (e.g., node 6 in Figure 2).
[0040] Smart contracts can be executed independently on each node of the blockchain network in a prescribed manner. All execution records and data are stored on the blockchain. Therefore, when such a transaction is completed, the blockchain stores an immutable and unlost transaction certificate.
[0041] As mentioned earlier, `storedData` in the example above is the state variable, which is stored in the smart contract's account storage. In various blockchain networks that introduce smart contracts, such as Ethereum, accounts typically include two types:
[0042] Contract account: Stores the executed smart contract code and the values of the state within the smart contract code; it can typically only be activated by an external account.
[0043] Externally owned account: A user's account, such as an Ethereum owner's account.
[0044] The design of external and contract accounts is essentially a mapping from account addresses to account states. Account states typically include fields such as Nonce, Balance, Storage root, and CodeHash. Nonce and Balance exist in both external and contract accounts. CodeHash and Storage root attributes are generally only valid for contract accounts.
[0045] Nonce: A counter. For external accounts, this number can represent the number of transactions sent from the account address; for contract accounts, it can be the number of contracts created by the account.
[0046] Balance: The amount of Ether held by this address.
[0047] Storage root: The hash of the root node of an MPT tree, which organizes the storage of state variables for contract accounts.
[0048] CodeHash: The hash value of the smart contract code. For contract accounts, this is the hash value of the smart contract; for external accounts, since the smart contract is not included, the CodeHash field can generally be an empty string or a string of all zeros.
[0049] MPT stands for Merkle Patricia Tree, a tree structure that combines the features of Merkle Tree and Patricia Tree (a compressed prefix tree, a more space-efficient Trie tree, also known as a dictionary tree). The Merkle Tree algorithm calculates a hash value for each transaction, then joins each pair of transactions and calculates the hash again, continuing until the top-level Merkle root. Ethereum uses an improved MPT tree, such as a 16-ary tree structure, which is often simply referred to as an MPT tree.
[0050] The Ethereum MPT tree data structure includes a state trie. The state trie contains key-value pairs (kv) representing the storage content for each account in the Ethereum network. The "key" in the state trie can be a 160-bit identifier (such as the address of an Ethereum account or part of its hash value, hereinafter referred to as the account address), distributed across storage from the root node to the leaf nodes of the state trie. The "value" in the state trie is generated by encoding the information of the Ethereum account using recursive-length prefix encoding (RLP). As mentioned earlier, for external accounts, the value includes nonce and balance; for contract accounts, the value includes nonce, balance, codehash, and storageroot.
[0051] A contract account is used to store the state of a smart contract. Once a smart contract is deployed on the blockchain, a corresponding contract account is created. This contract account typically has several states defined by state variables within the smart contract, which generate new values during the smart contract's creation and execution. A smart contract generally refers to a contract defined in code within a blockchain environment that can automatically execute its terms. Once an event triggers a term in the contract (meeting the execution conditions), the code can execute automatically. In the blockchain, the contract's state is stored in a storage trie. The hash value of the storage trie's root node is stored in the aforementioned storage root, thus locking all the contract's states to this contract account through hashing. The storage trie is also an MPT tree structure, storing a key-value mapping from state addresses to state values. Information from the root node to the leaf node of the storage trie tree is arranged sequentially to store the address of a state, and the leaf node stores the state's value.
[0052] As shown in Figure 3, in some blockchain data storage, each block header includes several fields, such as the previous block hash (prev_Hash in the figure), a nonce (in some blockchain systems, this nonce is not random, or the nonce in the block header is not enabled), a timestamp, a block number, a state root hash (State_Root), a transaction root hash (Transaction_Root), and a receipt root hash (Receipt_Root). The Prev Hash in the header of the next block (e.g., block N+1) points to the previous block (e.g., block N), which is the hash value of the previous block. In this way, the blockchain achieves the locking of the previous block by the next block through the block header. Specifically, State_Root, Transaction_Root, and Receipt_Root lock the state set, transaction set, and receipt set, respectively. The state set, transaction set, and receipt set are organized in a tree structure. Generally, they can be the same tree structure or different tree structures. For example, Ethereum uses the same MPT structure. In some tree structures like Ethereum that include a set of smart contract states, there is a two-level MPT structure: the leaf nodes of the upper-level MPT structure include two types: external accounts and contract accounts; each contract account includes the lower-level MPT structure, and the leaf nodes of the lower-level structure include the values of the state in the contract account.
[0053] Figure 4 is a schematic diagram of a blockchain data storage structure. Taking Ethereum as an example, and referring to Figure 3, `state_root` is the hash value of the root of the MPT tree composed of the states of all accounts in the current block. In other words, pointing to `state_root` is an MPT-form state trie. The root node of this MPT tree is generally an extension node or a branch node, and `state_root` typically stores the hash value of this root node. The root node can be connected to one or more layers of extension nodes / branch nodes below it; these multi-layered tree nodes can be collectively referred to as internal nodes. A portion of the values from each node from the root node to the leaf node in this MPT can be concatenated sequentially to form an account address as the key. The account information stored in the leaf node is the value corresponding to this account address, thus forming a key-value pair. This key can also be a partial SHA3 hash of the address, i.e., a portion of the hash value of the account address (using a hash algorithm such as SHA3). The stored value can be an RLP (Account), i.e., the RLP encoding of the account information. The account information is a four-tuple consisting of [nonce, balance, storageRoot, codeHash]. As mentioned earlier, for external accounts, generally only the nonce and balance fields are present, while the storageRoot and codeHash fields default to storing empty strings / strings of all zeros. That is, external accounts do not store contracts or the state variables generated after contract execution. Contract accounts generally include Nonce, Balance, Storage root, and CodeHash. Nonce is the transaction counter for the contract account; Balance is the account balance; Storage root corresponds to another MPT, which links to contract-related state information; CodeHash is the hash value of the contract code. Whether external or contract accounts, their account information is generally located in a single leaf node. From the root node's Extension Node / Branch Node to each account's Leaf Node, there may be several branch nodes and extension nodes in between.
[0054] The state trie can be an MPT-style tree, typically a 16-ary tree, meaning each level can have a maximum of 16 child nodes. An Extension Node, used to store a common prefix, typically has one child node, which can be a Branch Node. A Branch Node can have a maximum of 16 child nodes, which may include Extension Nodes and / or Leaf Nodes.
[0055] For a contract account within the state trie, its `storage_root` points to another tree, also in MPT form, which stores data related to the contract's execution state variables. This `storage_root` points to an MPT-form tree called the Storage Trie, specifically the hash value of the root node. Generally, this Storage Trie also stores key-value pairs. The key represents the address of the state variable, and its value can be the result of processing the state variable's declaration position (counting from 0) according to certain rules, such as SHA3(state variable declaration position) or SHA3(contract name + state variable declaration position). The value stores the state variable's value (e.g., an RLP-encoded value). A portion of the data stored along the path from the root node through intermediate nodes to the leaf node forms the key, and the leaf node stores the value. As mentioned earlier, this Storage trie can also be an MPT-type tree, typically a 16-ary tree. This means that a Branch Node can have a maximum of 16 child nodes, which may include Extension Nodes and / or Leaf Nodes. An Extension Node typically has one child node, which can be either a Branch Node or a Leaf Node.
[0056] For example, Leaf Node Account P in the state trie in Figure 4 is a contract account whose Storage Root locks all the states stored in the contract. These states are organized as an MPT tree, with a tree structure like the Storage trie linked by the Storage Root. In this linked Storage trie, taking Leaf Node State Variable N as an example, if it is the value of storedData in the aforementioned contract code example, then its key is sha3 (the declaration location of storedData, i.e., line 2 of the code), and its value is s (for simplicity, the encoding format of the value is omitted here, such as RLP, and similarly, it will not be elaborated further). The key values are distributed sequentially from the root node to the leaf node (i.e., Leaf Node Variable N) of the storage trie.
[0057] For example, in the state Trie in Figure 4, Leaf Node Account C is an external account. Its key is sha3(Address C), which is the hash value of the address of account C (using a hash algorithm such as sha3). Its stored value can be (Account), where the account information Account is a tuple of [nonce, balance]. As mentioned earlier, since Account C is an external account, its account information consists of nonce and balance (codehash and storage root are omitted here, but similarly below). For example, if an external account has a nonce of 20 and a balance of 4550, then the leaf node State Variable C will store nonce = 20 and balance = 4550. The address of Account C is the key, and its values are distributed sequentially from the root node to the leaf node (i.e., Leaf Node Variable C) of the state Trie.
[0058] These states, including the key-value pairs of external accounts and contract accounts, are ultimately stored in the database. However, the database does not directly store the states of these accounts (i.e., it does not directly store their key-value pairs), but rather stores the key-value values of each tree node itself.
[0059] As shown in the example in Figure 5, in the upper-level MPT structure, for leaf node A1, the key of the leaf node is formed by sequentially combining a7 of the shared nibble in the root node A8 (Extension Node), slot 1 of the intermediate node A7 (Branch Node), and key-end 1335 in leaf node A1, which is a711335. Balance = 45.0ETH and Nonce = n1 are stored in this leaf node. For leaf node A2, the key of the leaf node is formed by sequentially combining a7 of the shared nibble in the root node A8 (Extension Node), slot 7 of the intermediate node A7 (Branch Node), d3 of the shared nibbles in node A6 (Extension Node), slot 3 of the intermediate node A5 (Branch Node), and key-end 7 in leaf node A2, which is a77d337. Balance = 1.00ETH and Nonce = n2 are stored in this leaf node. For leaf node A3, the key of this leaf node is formed by sequentially combining a7 from the shared nibble in root node A8 (Extension Node), slot f from intermediate node A7 (Branch Node), and key-end 9365 in leaf node A3, resulting in a7f9365. This leaf node stores Balance = 1.1 ETH and Nonce = n3. For leaf node A4, the key of this leaf node is formed by sequentially combining a7 from the shared nibble in root node A8 (Extension Node), slot 7 from intermediate node A7 (Branch Node), slot d3 from the shared nibbles in node A6 (Extension Node), slot 9 from intermediate node A5 (Branch Node), and key-end 7 in leaf node A4, resulting in a77d397. This leaf node stores Balance = 0.12 ETH, Nonce = n4, CodeHash = c1, and Storage root = s1. s1 can be H(A10), which is the hash of the root node A10 of the next level tree. The leaf nodes of A1, A2, and A3 store information about external accounts, while the leaf node of A4 stores information about contract accounts. For each contract account, there is a next-level MPT, forming a Storage Trie used to store the state variables of that contract account.
[0060] As shown in the example of Figure 5, in the next-level MPT structure, for leaf node A11, through slot 3 in root node A10 (Branch Node) - key-end 35b2e4 in leaf node A11, they are sequentially combined to form the key of this leaf node, which is 335b2e4. In this leaf node, "Zhang San_A = 20" is stored. For example, it means that the share of type A digital assets defined in the contract belonging to Zhang San is 20, that is, the balance of Zhang San's type A assets is 20. For leaf node A12, through slot 7 in root node A10 (Branch Node) - key-end c25988 in leaf node A12, they are sequentially combined to form the key of this leaf node, which is 7c25988. In this leaf node, "Li Si_B = 20" is stored. For example, it means that the share of type B digital assets defined in the contract belonging to Li Si is 50, that is, the balance of Li Si's type B assets is 50. For leaf node A15, through slot f in root node A10 (Branch Node) - shared nibble a in intermediate node A13 (Extension Node) - slot 6 in intermediate node A14 (Branch Node) - key-end be33 in leaf node A15, they are sequentially combined to form the key of this leaf node, which is fa6be33. In this leaf node, "storedData = s" is stored. For leaf node A16, through slot f in root node A10 (Branch Node) - shared nibble a in intermediate node A13 (Extension Node) - slot 9 in intermediate node A14 (Branch Node) - key-end 9365 in leaf node A16, they are sequentially combined to form the key of this leaf node, which is fa99365. In this leaf node, "Wang Wu_A = 35" is stored. For example, it means that the share of type A digital assets defined in the contract belonging to Wang Wu is 35, that is, the balance of Wang Wu's type A assets is 35.
[0061] In the node composition of the above MPT tree, the tree node type is represented by prefix prefix. For example, 0 represents an Extension Node containing an even number of shared nibbles, 1 represents an Extension Node containing an odd number of shared nibbles, 2 represents a Leaf Node containing an even number of nibbles, and 3 represents a Leaf Node containing an odd number of nibbles.
[0062] In the above node structure, the hash value of the entire content of the next tree node is filled into the corresponding position of the previous tree node. The database actually stores the key-value mapping for each tree node, where the value includes the content stored in that tree node, and the corresponding key is the hash value of the entire content of that tree node. Thus, the actual key-value pairs of the tree nodes stored in the database are shown in the following table:
[0063] Table 1. Key-value pairs of tree nodes actually stored in the database.
[0064] In Table 1 above, H() represents hash calculation. This anchors the hash value of the next tree node to the previous tree node. Through this layer-by-layer hashing, the root hash of the entire state trie tree is obtained, and this root hash is locked into the state root field of the block header.
[0065] In some blockchain systems, the blockchain platform's code may include P2P (Peer-to-Peer) modules, consensus modules, execution modules, and storage modules. P2P is a way of organizing computer networks; unlike common web networks, P2P is decentralized and distributed. P2P modules enable the distributed propagation of data. For blockchain nodes, P2P modules allow for the peer-to-peer transmission and reception of receipts. Different participants can establish a distributed blockchain network through deployed nodes. The ledger constructed using a chain-like block structure is stored on each node (or most nodes, such as consensus nodes) in the distributed blockchain network; this is also known as a decentralized (or multi-centralized) distributed ledger. Such blockchain systems need to address the issue of consistency and correctness of the ledger data across multiple decentralized (or multi-centralized) nodes. Each node runs the same blockchain platform program. With a certain level of fault tolerance, the consensus module ensures that all loyal nodes have the same transactions, guaranteeing consistent execution results for the same transactions. The transactions and execution results are then packaged into blocks. Current mainstream consensus mechanisms include Proof of Work (POW), Proof of Stake (POS), Delegated Proof of Stake (DPoS), Practical Byzantine Fault Tolerance (PBFT), and Honey Badger Byzantine Fault Tolerance (HoneyBadgerBFT). During the consensus process, the consensus module can also generate timestamps for the blocks corresponding to the current transaction set. The execution module can execute transactions, including ordinary transfers and transactions involving contracts, either before or after the consensus module completes consensus. For transactions involving contracts, the execution module can introduce a virtual machine, such as the Ethereum Virtual Machine (EVM), to execute the smart contract code. This EVM shields the differences in hardware configuration and software environment across nodes, ensuring that the process and results of smart contract execution are identical on all nodes. Furthermore, the sandbox environment prevents smart contract execution from impacting the blockchain platform code, other programs, or the operating system on the host machine. In one scenario for a consortium blockchain, nodes can determine the content and order of transactions in a transaction set through a consensus module, and then output a deterministic transaction set as the consensus result to the execution module. The execution module generates execution results by executing ordinary transfer transactions or transactions involving contracts, and sends them to the storage module. The storage module is responsible for storing the execution results in persistent storage media on the node's local machine.
[0066] As shown in Figure 6, a blockchain node physically includes a CPU, memory, and disk. The blockchain platform code executed by this node can include a P2P module, a consensus module, an execution module, and a storage module. The P2P, consensus, and execution modules generally require CPU and memory to function. The storage module can include a tree construction module, a block header generation module, a WAL (Write Ahead Log) module, and a state database module. The tree construction module is used to build a tree (e.g., an MPT tree) based on the state key-value pairs passed from the execution module, such as the aforementioned state trie and storage trie, thus obtaining the key-value pairs of the tree nodes; this generally requires CPU and memory. The block header generation module is used to generate block headers based on the root node of the tree constructed by the tree construction module and other data (such as the previous block hash, timestamp, block number, etc.); this generally requires CPU and memory. The WAL module persistently stores the key-value pairs (kv) of the leaf nodes of the tree generated by the tree-building module before writing them to the state database module. This prevents data loss due to power outages or other unforeseen circumstances during the writing process and allows for data recovery in such cases. It typically requires the participation of CPU, memory, and disk. The state database module stores the key-value pairs of the tree nodes (kv) constructed by the tree-building module, as shown in Table 1, on a persistent storage device. Since the tree node data will ultimately be written to persistent storage media (such as the disk in the diagram), the state database module generally requires the participation of disk in addition to CPU and memory.
[0067] From a storage structure perspective, the aforementioned Merkle tree structures, such as Ethereum's MPT and Libra's SMT (Sparse Merkle Tree, similar to MPT), can reside in the tree construction module and be stored in memory, according to the correspondence shown in Table 1. The upper-level Merkle tree is a prefix tree (prefix tree), capable of organizing data and providing a unique Merkle root for the organized data. Leaf nodes store state values, and the root node, intermediate nodes, and leaf nodes provide a lexicographical index of the state keys. These tree nodes are encoded as keys according to certain rules, and their contents are encoded as values, ultimately stored in the lower-level database. The database mostly adopts an LSM (Log-Structured Merge-Tree) type NoSQL Key-Value DB (Database; Key-Value DB is also simply KVDB), located in the state database module and ultimately stored on disk. Specific examples include Ethereum's LevelDB and Libra's RocksDB. Both of these KVDBs are based on the LSM storage engine.
[0068] The LSM storage engine is a tiered, ordered, disk-oriented storage engine that borrows from the append-only (rather than modify) nature of the Log. Its core idea is to fully leverage the fact that sequential, batch writes to disk are far more efficient than random writes, sacrificing some read efficiency for maximum write efficiency. Generally, maximizing disk performance involves reading or writing a fixed-size block of data at a time, minimizing random access operations. LSM's design is based on this disk characteristic and assumes sufficient memory. Instead of writing data to disk every time it's updated, it first keeps the latest data in memory. Once a sufficient amount of data has accumulated, it uses merge sort to combine the data in memory with the data on disk and appends it to disk in batches.
[0069] The following uses Figure 7 as an example to further illustrate the storage process of the state data module. After the tree building module generates tree node key-value data and sends it to the storage module, this key-value data is first written to the Write-Ahead Log (WAL) in an append-only manner and stored on the disk. Then, the tree node key-value data is passed to the state database module. As mentioned earlier, writing to the WAL first prevents data loss due to power outages or other events during the writing of the tree node key-value data generated by the tree building module to the state database module, and allows for data recovery in such cases. After receiving the tree node key-value data, the state database module first stores it in memory, specifically in a MemTable within memory. The MemTable can provide concurrent read and write operations. Multiple MemTables can exist in memory. When the amount of data in a MemTable reaches a certain threshold, such as 256MB, the data in the MemTable can be flushed to the disk. To avoid write operations to the MemTable blocking the flush process, this MemTable is converted into an immutable Memtable, meaning the Immutable Memtable is set to read-only, and a new MemTable is created to receive the newly passed tree node key-value pairs. This new MemTable can provide concurrent read and write operations (as shown in the New MemTable diagram). The storage engine writes the data in the Immutable MemTable to disk.
[0070] On disk, KVDB stores data in multiple levels of SST (Sorted String Table) files. SST originates from the Google Bigtable paper. Bigtable is a distributed data storage system designed by Google to handle massive amounts of data; it's a non-relational database. SST can be used to store data files within Bigtable and is an efficient key-value file storage format. Content stored on persistent storage media can also be called a file.
[0071] SSTs can include multiple layers, such as 3, 4, 5, 6, 7, or more. Figure 7 shows a 3-layer case, namely level 0, level 1, and level 2. Generally, the total capacity of the SST in the upper layer is significantly smaller than that in the lower layer. For example, the total capacity of the SST in level 0 is 1GB, the total capacity of the SST in level 1 is 10GB, and the total capacity of the SST in level 2 is 100GB. Assume the capacity of the MemTable is 256MB. Tree construction modules can be written using the key-value pairs (kv) of the tree nodes corresponding to blocks, and then written to the MemTable. After writing the tree kv corresponding to one or more blocks to the MemTable, the space occupied by the MemTable may reach 256MB. Then, this MemTable is converted into an Immutable MemTable, and the data in the Immutable MemTable can be written (flush, which refers to the operation of writing data in memory to disk) to disk. Specifically, the data in the MemTable can be flushed to the Level 0 SST on disk. On the other hand, as mentioned earlier, a new MemTable is generated to receive the newly passed tree node kv and to provide concurrent read and write operations.
[0072] As mentioned earlier, each level of disk storage can include multiple SST files. The key-value pairs (kv values) stored in the SSTs of Level 1 and lower levels are generally stored in key order, and the key values in different SSTs within the same level are also ordered and non-repeating. For example, Level 1 includes 3 SSTs, and the SST11 on the left contains 1000 key-value pairs. <k1-v1> <k2-v2> <k3-v3> ... <k1000-v1000>And arranged in ascending order of k, for example, k1 = 10b43c032a46, k2 = 1118d46f41e1, k3 = 1b44942a3d6e, ..., k1000 = 2018df9326a7. It can be seen that SST11 on the left contains k1 < k2 < k3 < ... < k1000, but k1, k2, k3, ... k1000 are not necessarily consecutive. Similarly, SST12 in the middle, for example, contains 800 kv... <k1-v1> <k2-v2> <k3-v3> ... <k800-v800>And arranged in ascending order of k, for example, k1 = 21a514c0a7e1, k2 = 21b46b994214, k3 = 21b489571b6d, ..., k800 = 284a5df3fca7. It can be seen that the middle SST12 contains k1 < k2 < k3 < ... < k800, but similarly, k1, k2, k3, ... k800 are not necessarily consecutive. Similarly, the right-hand SST13, for example, includes 1100 kv. <k1-v1> <k2-v2> <k3-v3> ... <k1100-v1100>The k values are arranged in ascending order, for example, k1 = 3a5e55ac3fe1, k2 = 3a5e55ac3fe2, k3 = 3afb8ed31526, ..., k1100 = 400a51ef1405. It can be seen that in the SST13 on the right, k1 < k2 < k3 < ... < k1100, but similarly, k1, k2, k3, ... k1100 are not necessarily consecutive. Furthermore, overall, the minimum value of k in the left SST11 < the maximum value of k in the left SST11 < the minimum value of k in the middle SST12 < the maximum value of k in the middle SST12 < the minimum value of k in the right SST13 < the maximum value of k in the right SST13. The same applies to each level, Level 2, Level 3... That is, within each SST in each level, there is an order of magnitude in the value of k; and among multiple SSTs in each level, there is a range of magnitude in the value of k.
[0073] In Level 0, key-value pairs (kv) within a single SST can be sorted according to the size of their k values. However, the k values across multiple SSTs do not necessarily have a range-based relationship. This is because the MemTable typically stores multiple kv values corresponding to each block in ascending order (either from oldest to newest block number or from smallest to largest block number, since newer blocks have larger block numbers and older blocks have smaller block numbers). These k values are the hash values of tree nodes, and changes in the content of tree nodes are highly likely to result in significantly different hash values (i.e., k values). Sorting the kv values within an SST in Level 0 according to their k values is efficient and feasible in memory; however, sorting by k values is not strictly prohibited. For example, when the MemTable's capacity reaches 256MB, it may store multiple kv values corresponding to multiple blocks. This MemTable is then converted into an Immutable MemTable. These kv values in the Immutable MemTable can be sorted by their k values and written to the left-hand SSTs in Level 0. There may be multiple processes of writing different Immutable MemTables to the same SST before filling SST01 on the left side of Level 0, and then writing to SST02 on the right side of Level 0 can be done in a similar way. Although the key-value pairs (kv) written to a particular SST in Level 0 by a single Immutable MemTable are sorted, the sets of kv written by different Immutable MemTables within the same SST in Level 0 are generally not sorted by size, and the kv pairs between different SSTs (e.g., left and right SSTs) are also not sorted by size. That is, the ranges of k in the left and right SSTs in Level 0 may overlap. Similarly, since the kv written to an SST in Level 0 can be written after multiple MemTables are full, and the ranges of kv in the multiple MemTables are full generally overlap, the multiple kv stored in each SST in Level 0 generally do not have a specific order, and there is generally no specific range order between the SSTs in Level 0. Of course, if an SST is written to from an Immutable MemTable in Level 0 in a single write, then since the Immutable MemTable sorts the key-value pairs when writing to the SST, the key-value pairs stored in the SST will also be sorted according to the key.
[0074] Furthermore, when the storage capacity of Level 0 reaches or approaches its limit, a process called "compaction" is used to write the data from Level 0 into Level 1. During this compaction process, the key-value pairs (kv) in each SST within Level 0 and some or all of the kv in Level 1 SSTs can be first transferred to memory, sorted in memory, and then written to the Level 1 SSTs. Because sorting occurs during compaction, within Level 1 SSTs, there is a size order relationship in the value of k, and across multiple Level 1 SSTs, there is a size order relationship in the range of k. In other words, within each Level 1 SST, the kv values are ordered according to... <k1-v1> <k2-v2> <k3-v3> ... <kn-vn>The SSTs are arranged in a specific order, where k1 < k2 < k3 < ... < kn, but k1, k2, k3, ... kn are not necessarily consecutive. Furthermore, overall, for any two adjacent SSTs, the minimum value of k in the left SST < the maximum value of k in the left SST < the minimum value of k in the right SST < the maximum value of k in the right SST. This is illustrated in Figure 8.
[0075] During compaction, the key-value pairs (kv) in each SST within Level 0 and the key-value pairs in some SSTs within Level 1 can be loaded into memory for sorting. The SSTs within Level 1 can be SSTs whose key-value ranges overlap with those in Level 0; that is, SSTs whose key-value ranges overlap with those in each SST of Level 0. Specifically, for example, in the example above, Level 1 includes three SSTs: SST11 has a key range of 10b43c032a46 to 2018df9326a7; SST12 has a key range of 21a514c0a7e1 to 284a5df3fca7; and SST13 has a key range of 3a5e55ac3fe1 to 400a51ef1405. For example, the key range in each SST within Level 0 is 18c49a405e32 to 24d35f39ab56. As can be seen, SST11 and SST12 overlap with the key range in Level 1 and Level 0. Thus, during compaction, the key-value pairs in each SST in Level 0 and the key-value pairs in SST11 and SST12 in Level 1 can be transferred into memory and sorted, and then the sorted results are written back to the SST in Level 1.
[0076] Similarly, when the storage capacity of Level 1 reaches its limit, a compaction process is used to write the data from Level 1 to Level 2. During this compaction process, the key-value pairs (kv) of each SST in Level 1 and some or all of the kv of some SSTs in Level 2 can be first loaded into memory, sorted in memory, and then written to the SSTs of Level 2. Likewise, if there is a Level 3 below Level 2, when the storage capacity of Level 2 reaches its limit, a compaction process is used to write the data from Level 2 to Level 3. Again, during this compaction process, the key-value pairs of each SST in Level 2 and some or all of the SSTs in Level 3 can be first loaded into memory, sorted in memory, and then written to the SSTs of Level 3. And so on.
[0077] In this way, overall, the data stored in the upper-level SST is newer than that in the lower-level SST. The newest data is stored in memory, the second newest data is stored in Level 0, and so on, with the oldest data stored in the SST within the lowest level. Furthermore, compaction can be used for garbage collection, such as deleting data marked for deletion.
[0078] Sorted key-value pairs can be efficiently retrieved, for example, using binary search. Binary search, also known as half-interval search, has the following algorithm: Define `left` as the leftmost element position of the sequential list, `right` as the rightmost element position, and `mid` as (left + right) / 2, which is the middle position of the sequential list; compare the value to be searched with the value at position `mid`; since the list is ordered, if the value to be searched is smaller than `mid`, only the first half of the list needs to be searched; otherwise, only the second half needs to be searched (if the two values are equal on the first comparison, the current value's position is returned directly). This process continues until the value is found or it is determined that the value to be searched is not in the list (i.e., the search fails).
[0079] Such storage engines suffer from read amplification and write amplification issues when reading and writing data, which will be explained in detail below.
[0080] In a blockchain system employing the aforementioned storage engine, the execution module may need to read an existing state during transaction execution. For example, in a typical transfer transaction, external account A transfers a certain amount (e.g., f) of assets to external account B, requiring adjustments to the account balances. Assuming that before the transaction, account A's balance is a and account B's balance is b, the transaction execution sets account A's balance to (af) and account B's balance to (b+f). Therefore, this transaction needs to read the values of the state variables a and b during execution. Another example is a contract call transaction. External account C initiates a call to contract D. C initiates a transaction pointing to the address of contract account D, specifying the called function and input parameters in the transaction's data field. Assuming the called function in contract D includes judging the value of a global state d within the contract (assuming d is a boolean), the judgment logic includes executing branch 1 if true and branch 2 if false. Therefore, this contract call transaction needs to read the value of state d during execution.
[0081] During transaction execution, whether reading the values of state variables a and b, or reading the value of state variable d, the execution module can first check if the value of that state variable exists in its own memory. If it does not exist, a read command is sent to the storage module. This read command can include the address of the state to be read, i.e., the state's key value. Upon receiving the read command, the storage module locates the root node of the state tree in the tree construction module. It then matches the state key value to be searched against the root node's shared nibble(s) field (for Extension Nodes) or slot (for Branch Nodes) from the beginning. Next, it reads the hash of the next-level tree node (which can be an Internal Node or a Leaf Node; we will use an Internal Node as an example) from the matched position. It then first searches for the hash in the tree construction module's memory. If it is not found there, it searches in the state database module's memory. If it is still not found there, it searches in the state database module's file. Specifically, the search can begin within the SSTs of Level 0. If the hash value is not found there, the search continues within an SST of Level 1, and so on, down to the next SST of the next lower level, until the next Internal Node pointed to by the hash value is found. After unpacking this Internal Node, the remaining fields of the key value of the state address to be read are matched from front to back. If a match is found, the hash value is read from the match point, and the user jumps to the next level tree node pointed to by that hash value. This process is repeated, unpacking Internal Nodes level by level and matching the remaining fields of the key value of the state address to be read from front to back. The hash value at the match point serves as the basis for the next search of intermediate or leaf nodes, until a Leaf node is matched, from which the state value is read. During this process, some key-value pairs of tree nodes at each level may not exist in the memory of the tree building module but are located in the state database module. Therefore, it may be necessary to read them from the state database module into memory for operations. The key can be searched first in the MemTable or Immutable MemTable of the state database module. If it does not exist, further searching of the various levels of SST files on disk is required. For Internal Nodes and Leaf Nodes existing on disk, they need to be loaded into memory and decoded (deserialized) to obtain their contents. Specifically, for example, the search can begin by sequentially searching the SST files of level 0. If each SST in level 0 is sorted, a binary search can be performed within each SST based on the hash value of the intermediate / leaf node. Once found, the key (v) is loaded into memory and decoded and matched.If the value is not found in the SST at Level 0, a binary search is performed in Level 1 based on the hash value of the intermediate / leaf node. If the value is still not found, a binary search is performed in Level 2. If the value is found, the value corresponding to the k is loaded into memory and decoded. This process continues until a leaf node of the tree structure is matched and its value is read. Since the overall SST at Levels 1, 2, and lower levels is sorted, a binary search can generally be performed at each level.
[0082] From the above process of reading a state key-value pair, it can be seen that this reading process requires binary search in multiple SSTs at different levels based on the hash value of the tree node. This may require reading a large number of files in multiple SSTs and loading them into memory, which leads to read amplification. Assuming the database includes Level 0, Level 1, Level 2, ..., Level M-1, for a total of M levels, then in the worst case, reading the data of a state requires at least M disk accesses (greater than M because in the worst case, N SSTs at Level 0 may require more than 1 but less than or equal to N search operations).
[0083] Furthermore, if the tree-building module is missing a key-value pair (kv) for a particular tree node while constructing the path from the state key-value pair to the root node, it may need to perform a binary search from Level 0, Level 1, Level 2, etc., with a similar principle to the process described above. In the transaction example above, for instance, after the transaction is executed, the value of the execution result (af), the value of (b+f), and the value of the contract state d need to be written to the state database. For the values to be written to the database, the execution module calls the storage interface of the storage module, outputting the key-value pairs of the state to the storage module. The tree-building module in the storage module generates the key-value pairs of the tree nodes from the root to the intermediate and leaf nodes based on the state key-value pairs, writes these key-value pairs to the WAL module, and then writes this series of key-value pairs to the MemTable of the state database module, marking them as dirty data. Dirty data typically refers to data that has been written to the MemTable but has not yet been written to persistent storage (such as SSTable). Dirty data can be written to disk during the aforementioned flush process. The state database module then writes some key-value pairs, including the tree node key-value pairs, from the MemTable to the SST file on disk. Once the MemTable is persisted to the SSTable, the data within it is no longer dirty data, i.e., it becomes "clean" data. It is evident that the above process of persistently storing a state key-value pair is quite complex, consumes significant computational and memory resources, and introduces write amplification issues.
[0084] The complexity of the read and write processes, as well as the read amplification and write amplification issues, pose challenges to the high-performance requirements and large-scale applications of blockchain.
[0085] This application provides an embodiment of a method for reading blockchain state data. This method embodiment can be applied to the storage module of a blockchain node. The storage module constructs a tree-structured world state in memory. The leaf nodes of the tree structure may include the content of the state data or the position index of the state data within a data file in a persistent storage medium.
[0086] In one example, the overall tree structure can be shown in Figure 10, which is somewhat similar to Figure 5. Specifically, if the leaf nodes in memory contain state data, it can be as shown in Figure 5. For example, leaf node A11 in Figure 5 contains state data in memory, i.e., Zhang San_A = 20. If the leaf nodes in memory do not contain state data, the index storing the state data in the data file can be used.
[0087] In this application, separating the actual data and the index helps improve the system's flexibility and performance. The basic concepts involved include data files and index files. The data file stores the actual content; the index file stores an index pointing to the location of the data file. Its working principle is as follows: data content is written to the data file, recording the data's position within the file (such as filename, offset, and length); then, an entry is created in the index file, containing a key (a unique identifier used for lookup) pointing to a reference in the data file (filename, offset, etc.). Thus, during data retrieval, the data location can be quickly located through the index file, and the actual content can be read from the data file based on the location information. The advantages of this approach are: ① Flexibility: data and indexes can be managed and optimized independently; ② Performance: indexes are typically small and can be fully loaded into memory, speeding up queries; ③ Space efficiency: avoiding the storage of large amounts of duplicate data in the index; ④ Update efficiency: when modifying data, only the location information in the index needs to be updated.
[0088] For example, in Figure 10, the location index is used to represent this position. Taking node A11 as an example again, if there is no state data in memory, the location field can be used to store the position index of the data file containing the state data. This position index is, for example, <2,750,210>. This <2,750,210> indicates that the state data is located in "File 2" within the data file, starting at the 750th KB position of "File 2" and having a length of 210KB. As shown in the lower left corner of Figure 10, assuming each file is 1024KB in size, the logical address range of the index is 0KB to 1023KB. Thus, the state data of A11 actually occupies the range from the 750th KB to the 959th KB position in File 2.
[0089] As shown in Figure 9, this embodiment includes:
[0090] S910: The storage module of the blockchain node receives the instruction to look up the state key and searches for the leaf node corresponding to the state key in the tree structure in memory.
[0091] As shown in Figure 6 above, the execution module can generate execution results by executing ordinary transfer transactions or transactions involving contracts, and then send them to the storage module. Specifically, for example, during contract execution, it may be necessary to read the value of a state variable. The execution module can first check if the value of the state variable exists in its own memory. If it does not exist, it sends a read instruction to the storage module. This read instruction can include the address of the state to be read, i.e., the state's key value.
[0092] The storage module includes a tree-building module. This module constructs a tree structure representing the world state in memory. In the case of a cold start of a blockchain node (i.e., before the world state tree structure exists in memory), the individual tree nodes can be loaded from disk and organized into a tree in memory. This process also involves loading leaf nodes. An example is given where the tree-building module contains an incomplete tree structure; the cold start loading process is similar. Since memory capacity is generally limited, the LRU (Least Recently Used) algorithm is typically used to evict tree nodes that haven't been accessed for a long time. Therefore, leaf nodes in the tree structure constructed in memory by the tree-building module may be subject to eviction. For the leaf nodes of the world state tree, some may be in memory while others may not. Furthermore, a similar eviction mechanism can be used for the content within tree nodes, such as the state data in leaf nodes; alternatively, state data may not be maintained in memory.
[0093] For the state key to be searched, if the tree construction module has a leaf node corresponding to the state key in memory, it can be found directly in memory. Referring to Figure 5, the key of the corresponding leaf node can be found directly in memory, and the value can be read from it. Then, the state data can be read from the value. If the tree construction module does not have a leaf node corresponding to the state key in memory, or if the leaf node exists but does not contain the state data to be searched, further searching is required in the state database module. For cases where the state database uses an LSM tree, as mentioned earlier, a search can be performed first in the MemTable; if not found, a search can be performed in the files on disk.
[0094] S920: Obtain the position index contained in the leaf node corresponding to the tree node key, where the position index points to the position within the data file in the persistent storage medium.
[0095] Even if the tree construction module has the leaf node to be searched in memory, but it does not contain state data, a further search is needed from the state database module. As mentioned earlier, if there is no state data in memory, the location field can be used. For example, in Figure 10, the location of leaf node A11 is <2, 750, 210>. This <2, 750, 210> is the location index, which indicates that the state data is located in file 2 of the data file, starting at position 750KB and with a length of 210KB. As shown in the data file in the lower left corner of Figure 10, assuming each file is 1024MB in size, the logical address range of the index is 0KB to 1023KB. Thus, the state data of A11 actually occupies the range from 750KB to 959KB in file 2.
[0096] If the leaf node to be searched is not in the memory of the tree construction module, it needs to be searched for and loaded from the state database module. Searching for and loading the leaf node from the state database module specifically includes loading the index file and data file of the leaf node. Assume that the underlying database corresponding to Figure 10 stores the key-value pairs (kv) of all intermediate nodes in the tree structure, as shown in the table below:
[0097] Table 2. Key-value pairs of tree nodes actually stored in the database.
[0098] In Table 2 above, similar to Table 1, H() represents hash calculation. This anchors the hash value of the next tree node to the previous tree node. Through this layer-by-layer hashing, the root hash of the entire state trie tree is obtained and locked to the state root field in the block header. Assume the key-value pairs in this table are stored in the underlying state database module, saved on disk, and using a similar LSM structure. Thus, similar to the above, after receiving a read command, the storage module can find the root node of the state tree in the tree construction module. It then matches the state key value to be searched against the root node's shared nibble(s) field (for Extension Nodes) or slot (for Branch Nodes) from the beginning. It reads the hash of the next level tree node from the matching position, and then first searches for the hash in the memory of the tree construction module. If it is not found there, it searches in the memory of the state database module. If it is still not found there, it searches in the state database module's file. Specifically, the search can begin within the SST at Level 0. If the hash value is not found there, the search continues within an SST at Level 1, and so on, down to the next SST at each lower level, until the next Internal Node pointed to by the hash value is found. After unpacking this Internal Node, the remaining fields of the key value of the state address to be read are matched from front to back. If a match is found, the hash value is read from the match point, and the search jumps to the next level tree node pointed to by that hash value. This process is repeated, unpacking Internal Nodes level by level and matching the remaining fields of the key value of the state address to be read from front to back. The hash value at the match point serves as the basis for the next search of intermediate or leaf nodes, until a Leaf node is matched, from which the state value is read. During this process, some key-value pairs of tree nodes at each level may not exist in the memory of the tree building module but are located in the state database module. Therefore, it may be necessary to read them from the state database module. The key can be searched first in the MemTable or Immutable MemTable of the state database module. If it does not exist, further searching of the various levels of SST files on disk is required. For Internal Nodes and Leaf Nodes existing on disk, they need to be loaded into memory and decoded (deserialized) to obtain their contents. Specifically, for example, the search can begin by sequentially searching the SST files of level 0. If each SST in level 0 is sorted, a binary search can be performed within each SST based on the hash value of the intermediate / leaf node. Once found, the key (v) is loaded into memory and decoded and matched.If the value is not found in the SST at Level 0, a binary search is performed in Level 1 based on the hash value of the intermediate / leaf node. If the value is still not found, a binary search is performed in Level 2. If the value is found, the value corresponding to the k is loaded into memory and decoded. This process continues until a leaf node of the tree structure is matched and its value is read. Since the overall SST at Levels 1, 2, and lower levels is sorted, a binary search can generally be performed at each level.
[0099] In this way, the key-value pairs of the found leaf nodes can be loaded into memory. For example, in A11, the content of the leaf node value, prefix:2, key-end:35b2e4, location: (2,750,210), is loaded into memory. Here, <2,750,210> is the position index of the value content in the file.
[0100] S930: Load the value of the data file location in the persistent storage medium pointed to by the location index into memory and read the status data therein.
[0101] Taking A11 as an example, the position index <2,750,210> points to the location within the data file in the persistent storage medium. Thus, the value at the location in the data file pointed to by the position index <2,750,210> can be loaded into memory and its status data read. Specifically, the 210KB data starting from the 750KB mark in file 2 of the data file can be loaded into memory, and its status data, "Zhang San_A = 20", can be read.
[0102] The location index allows direct location within the data file, enabling the loading of the data file and the reading of status data from it.
[0103] If the tree-building module has the leaf node to be searched in memory, but it does not contain state data, it can directly read the data from the corresponding data file based on the location within the leaf node in memory. This avoids storing the key-value pairs of the leaf node together in the persistent storage SST file, which would require multiple binary search operations within the SST.
[0104] If the leaf node to be searched is not in the memory of the tree construction module, and it is necessary to search for and load the leaf node from the state database module, it is actually necessary to read a certain amount of content from the disk into memory before searching. In the implementation corresponding to Table 1, the key-value pairs of the tree node are stored together on disk, and the value of the leaf node includes state data. For example, in Table 1, H(11) corresponds to Zhang San_A=20, H(12) corresponds to Li Si_B=20, H(15) corresponds to storedData=s, and H(16) corresponds to Wang Wu_A=20. Generally speaking, the state data occupies a large space, about 90% or more of the total space of a key-value pair. In the implementation corresponding to Table 2, the index and data are separated. The index stores the location of the data file containing the state data, but not the state data itself. For example, in Table 2, H(11) corresponds to location (2,750,210), H(12) corresponds to (3,350,210), H(15) corresponds to (5,760,140), and H(16) corresponds to location (5,170,210). The actual state is stored in the corresponding location in the data file, as shown in Figure 10. Therefore, in the process of searching for leaf nodes, only the index file can be searched. In this way, more index files can be loaded into memory within a unit space for searching. The search efficiency in memory is significantly higher than that on disk. Generally, the content to be searched is loaded into memory before searching. The implementation in Table 2 can find leaf nodes faster than the implementation in Table 1 because more indexes can be loaded within a unit capacity of memory space. The implementation of Table 1, for example, requires reading a batch of key-value pairs into memory. If a leaf node is not found, another batch of key-value pairs needs to be read into memory again for another search. Since the state content occupies a large amount of space, the number of key-value pairs in a unit of memory space is relatively small. Therefore, the number of reads from the disk will generally be more frequent. Since the disk read speed is much slower than memory, the search efficiency of the implementation of Table 1 is low.
[0105] The specific process of the method embodiment in Figure 9 is illustrated above with reference to Figure 10. Figure 10 still shows a two-level MPT tree structure, and the structure of the intermediate nodes in each level includes two types of tree nodes: Extension Node and Branch Node. In a variation, a Branch Node can be used as both the intermediate node and the root node, as shown in Figure 11. Thus, the sequential combination of slots in the branch nodes traversed from the root node through the intermediate nodes to the leaf nodes can constitute part of the content in the state key. The hash value of the next-level node can be stored in the slot of the previous-level node. In Figure 11, a two-level tree structure can still be used. The leaf nodes in the previous-level tree can store account states (including the states of external accounts and contract accounts), and the leaf nodes in the next-level tree store the contract states. Position indexes can be used in the leaf nodes storing external account states, contract account states, or contract states. For example, the leaf nodes of the previous-level tree include the account states in the following four rows: H(M1), H(M2), H(M3), and H(M4) in the table below:
[0106] Table 3. Key-value pairs of tree nodes actually stored in the database.
[0107] The location index allows direct access to the data file, enabling the loading of the data file and the reading of state data. Furthermore, the leaf nodes of the next-level tree contain the contract states as shown in rows H(Z1), H(Z2), H(Z3), and H(Z4) in the table above.
[0108] The data file is shown in Figure 11, and its contents are as follows:
[0109] M1: Nonce: n1, balance: 45.0 ETH
[0110] M2: Nonce: n2, balance: 1.00WEI
[0111] M3: Nonce: n3, balance: 1.1 ETH
[0112] M4:Nonce:n1,balance:0.12ETH,codehash:c1,storage:s1
[0113] Z1: Zhang San_A=20
[0114] Z2: Li Si_B=50
[0115] Z3: Wang Wu_A=35
[0116] Z4:storedData=s
[0117] Regardless of whether it's the parent or child level of the tree, the location in the leaf node can be quickly located to the position in the data file. This avoids the need for multiple binary search operations in the SST based on the leaf node's key (hash value) when storing the key-value pairs of the leaf nodes together in the persistent storage SST file. In the example of Figure 11, when reading blockchain state data as shown in Figure 9, the location in the data file can be directly located based on the location index. Therefore, the content located at the corresponding position in the data file can be directly loaded into memory, thus avoiding the read amplification problem caused by reading a large number of files from multiple levels of SST and loading them into memory. Similarly, the leaf node A4, which is also the parent level of the tree, can be stored as shown in Figure 10 or as shown in Figure 11.
[0118] External accounts and contract accounts typically use fixed-length strings as keys, while contract status keys can also be strings of the same length. Specifically, for example, the key for an external account or contract account could be an account address, while the key for the contract status could be a string of the same length. Another example is that the key for an external account or contract account could be the account address hashed using a specific algorithm, such as SHA3; while the key for the contract status could be SHA3(contract name + position of status variable declaration). These external accounts, contract accounts, and contract statuses are all strings of the same length and format, collectively referred to as the status key. For example, the length of the status key might be 4 bytes, or 32 bits. Thus, assuming the root node (B0) and intermediate nodes (..., C5, ..., C13, ..., C5D1, ..., C5D9, ..., C5D14, ..., C13D2, ..., C13D10, ...) are each 16-ary trees, then on the one hand, each slot in the intermediate node (such as slots 0, 1, 2, ..., d, e, f in B0, a total of 16 slots) can be filled with the hash value of the next tree node. On the other hand, the position of this slot in the root / intermediate node can represent a 4-bit key. 4 bits constitute a half-byte, so the root node and intermediate nodes, a total of 8 levels, can store 32 bits, totaling 8 bytes, which is the entire state key. The 32 bits of the state key can be stored from the top-level intermediate node to the bottom-level intermediate node and down to the leaf node, with each level storing one half-byte of the key. Thus, in the case where the intermediate nodes are fixed and expanded, the leaf nodes can store the last 4 bits of the key. With the intermediate nodes fixed and expanded, Figure 11 shows a total of 8 layers from C* to C13D*, all the way to the bottommost M*. Alternatively, a compressed prefix and / or infix and / or suffix approach can be used, in which case one or more leaf nodes plus the intermediate nodes above them can be fewer than 8 layers.
[0119] Alternatively, a single-layer tree structure can be used to store account and contract states, as shown in Figure 12. Since the key for a contract state is a hash value, due to the discrete nature of hash algorithms, the state keys for different contract states may follow paths from the root node to different leaf nodes within this single-layer tree structure. Thus, different states of the same contract may have values residing in different leaf nodes at the bottom layer of the tree structure, rather than clustered under their respective contract accounts. In effect, using a single-layer tree structure, both account and contract states are distributed across the bottom-layer leaf nodes.
[0120] Furthermore, based on Figure 12, as shown in Figure 13, when there are not many leaf nodes, prefix, infix, and / or suffix compression can be performed. For example, in the case of infix compression, if the key of tree node M1 is 0x52d1479e (0x represents each digit in hexadecimal), and the key of tree node Z1 is 0x52d9ab36, then M1 and Z1 share a common infix 2d. Therefore, in tree node C5, in addition to the 1 and 9 separated by the hexadecimal tree, C5 can also have compressed infix 2d, as shown in the shared nibbles field in Figure 13. For suffix compression, for example, using key-end representation, the key-end of tree node M1 is, for example, 479e, and the key-end of tree node Z1 is, for example, 36. Using prefix, infix, and / or suffix compression, the number of tree levels can be reduced.
[0121] Regardless of compression, to find a state key, one can start from the root node of the tree structure and match the path of the state key segment by segment until the leaf node of the tree structure corresponding to the state key is found. In one approach, the root node and intermediate nodes are stored in key-value format, where the key is the hash value of the value, similar to the structure in Table 3. In this way, one can start from the upper-level tree node, sequentially match the hash of the path of the state key, and use the hash to find the lower-level tree node until the leaf node of the tree structure corresponding to the state key is found.
[0122] Furthermore, the key of the tree node kv actually stored in the database may not be the hash value of the value, but a partial value on the state key path. For example, it may be a partial key value from the root node to the current tree node (refer to Figure 12, without compressed prefix / infix / suffix, as shown in Table 4), or a partial key value from the previous tree node onwards (refer to Figure 13, with compressed prefix / infix / suffix, as shown in Table 5).
[0123] Table 4. Tree node key-value pairs actually stored in the database
[0124] According to Table 4 and Figure 12, for example, if the search state key is 0x59...36 (leaf node Z1), starting from the root node of the tree structure, we can match the first digit (5) of the state key to the tree node in the database with the key 0x5 (the h (C5) in the value of the tree node with the key 0x5 can be used to verify with the hash value in slot 5 of the root node; if they are the same, it means that the tree node with the key 0x5 is a child node in slot 5 of the 0x tree node); then, we can match the second digit (9) of the state key to the tree node in the database with the key 0x9 (the h (C5D9) in the value of the tree node with the key 0x9 can be used to verify with the hash value in slot 9 of the parent node; if they are the same, it means that the tree node with the key 0x9 is a child node of the 0x5 tree node); and so on. Finally, the last digit 6 of the status key can be used to match the tree node in the database with the key 0x6 (the h(Z1) in the value of the tree node with key 0x6 can be used to verify with the hash value on slot 6 in the parent node; if they are the same, it means that the tree node with key 0x6 is a child node of the parent node).
[0125] Table 5. Tree node key-value pairs actually stored in the database
[0126] According to Table 5, for example, if the search query for the state key is 0x52d9...36 (leaf node Z1), starting from the root node of the tree structure, the system can match the first digit (5) of the state key in the database. If no matching key is found, or if the hash value in the value of the tree node matching the key is inconsistent with h(C5) in the root node, the system will again match the first two digits (52) of the state key in the database. This process is repeated until a match is found. When the system matches the first three digits (52d) of the state key in the database and finds a tree node with the key 0x52d, and the hash value H(C5) in its value is the same as the hash value in slot 5 of the root node, then a match has been found. Then, the system can match the first four characters (52d9) of the status key in the database. If no matching key is found, or if the hash value of the value in the tree node containing the matched key is inconsistent with h(C5) in the root node, the system can re-match the first two characters (52) of the status key in the database. If a match is found, and the H(C5D9) in the value of the matched tree node is the same as the hash value in slot 9 of the parent node, then a match has been found. Further, the system matches the first five characters (1-5) of the status key in the database, the first six characters (1-6) of the status key in the database, and so on, until a leaf node is matched.
[0127] In another implementation, the complete state key or the corresponding complete state key can be stored in the leaf nodes. Taking storing the complete state key in the leaf nodes as an example, as shown in Figure 14, the `key-full` field of the leaf node can store the complete key of the corresponding state. The key-value pair of the leaf node stored in the database has the key that is the complete key of the corresponding state for that leaf node. In this way, when searching for a state key, the key can be directly matched against the key of the leaf node in the database, without needing to match the keys of intermediate nodes. Obviously, this search method is extremely efficient for query operations. In fact, in Figures 10-13 above, the complete state key can also be used as the key of the leaf node.
[0128] In the embodiments shown in Figures 9-14 above, the location index is stored in the leaf node. This allows for quick location of the leaf node's value in the data file after the leaf node is found. This enables direct loading of the content at the corresponding location in the data file into memory, avoiding the read amplification problem caused by reading and loading large amounts of files from multiple levels of the SST. It also avoids the need for multiple binary search operations within the SST based on the leaf node's key (the hash value of the value) when storing the leaf node's key and value together in the persistent SST file. Furthermore, similarly, if the leaf node to be searched is not present in the memory of the tree-building module, the above embodiments can search only the index file. This allows more index files to be loaded into memory within a unit of space for searching, thus finding the leaf node faster.
[0129] This application also provides a blockchain node, which includes a storage module, a tree-building module, and persistent storage. The persistent storage medium includes an index file and a data file. The storage module also includes a search unit and a read unit. The leaf nodes of the tree structure include an index of the position of state data within the data file in the persistent storage medium.
[0130] The tree-building module is used to build the world state of a tree structure in memory;
[0131] The search unit receives an instruction to search for a state key, searches for the leaf node corresponding to the state key in the tree structure in memory, and obtains the location index contained in the leaf node, the location index pointing to the location in the data file in the persistent storage medium;
[0132] The reading unit loads the value of the data file location in the persistent storage medium pointed to by the location index into memory and reads the status data therein.
[0133] The search unit starts from the root node of the tree structure and matches the path of the state key segment by segment until it finds the leaf node of the tree structure corresponding to the state key.
[0134] The search unit starts from the previous level tree node and sequentially matches the hash of the path of the state key, and searches for the next level tree node based on the hash, until it finds the leaf node of the tree structure corresponding to the state key.
[0135] The search unit starts from the previous level tree node and sequentially matches the key of the path of the state key, and searches for the next level tree node based on the matched key, until it finds the leaf node of the tree structure corresponding to the state key.
[0136] When there is no state data in the leaf node in memory, obtain the position index contained in the leaf node.
[0137] When the leaf node does not exist in memory, the tree node key of the leaf node is searched in the index file in persistent storage, the value in the data file corresponding to the key is loaded into memory, and the position index is obtained from the value.
[0138] The tree node key of the leaf node in the tree structure corresponds to the state key. Therefore, when the leaf node does not exist in memory, the tree node key of the leaf node is retrieved from persistent storage.
[0139] When the leaf node does not exist in memory, the search unit searches for the tree node key of the leaf node in the persistently stored index file based on the status key.
[0140] The tree structure includes a single-layer tree structure or a two-layer tree structure.
[0141] In the 1990s, improvements to a technology could be clearly distinguished as either hardware improvements (e.g., improvements to the circuit structure of diodes, transistors, switches, etc.) or software improvements (improvements to the methodology). However, with technological advancements, many methodological improvements today can be considered direct improvements to the hardware circuit structure. Designers almost always obtain the corresponding hardware circuit structure by programming the improved methodology into the hardware circuit. Therefore, it cannot be said that a methodological improvement cannot be implemented using hardware physical modules. For example, a Programmable Logic Device (PLD) (such as a Field Programmable Gate Array (FPGA)) is such an integrated circuit whose logic function is determined by the user programming the device. Designers can program and "integrate" a digital system onto a PLD themselves, without needing chip manufacturers to design and manufacture dedicated integrated circuit chips. Furthermore, nowadays, instead of manually manufacturing integrated circuit chips, this programming is mostly implemented using "logic compiler" software. Similar to the software compiler used in program development, the original code before compilation must also be written in a specific programming language, called a Hardware Description Language (HDL). There are many HDLs, such as ABEL (Advanced Boolean Expression Language), AHDL (Altera Hardware Description Language), Confluence, CUPL (Cornell University Programming Language), HDCal, JHDL (Java Hardware Description Language), Lava, Lola, MyHDL, PALASM, and RHDL (Ruby Hardware Description Language). Currently, the most commonly used are VHDL (Very-High-Speed Integrated Circuit Hardware Description Language) and Verilog. Those skilled in the art should also understand that by simply performing some logic programming on the method flow using one of these hardware description languages and programming it into an integrated circuit, the hardware circuit implementing the logical method flow can be easily obtained.
[0142] The controller can be implemented in any suitable manner. For example, it can take the form of a microprocessor or processor and a computer-readable medium storing computer-readable program code (e.g., software or firmware) executable by the (micro)processor, logic gates, switches, application-specific integrated circuits (ASICs), programmable logic controllers, and embedded microcontrollers. Examples of controllers include, but are not limited to, the following microcontrollers: ARC 625D, Atmel AT91SAM, Microchip PIC18F26K20, and Silicon Labs C8051F320. A memory controller can also be implemented as part of the control logic of the memory. Those skilled in the art will also recognize that, in addition to implementing the controller in purely computer-readable program code form, the same functionality can be achieved by logically programming the method steps to make the controller take the form of logic gates, switches, application-specific integrated circuits, programmable logic controllers, and embedded microcontrollers. Therefore, such a controller can be considered a hardware component, and the means included therein for implementing various functions can also be considered as structures within the hardware component. Alternatively, the means for implementing various functions can be considered as both software modules implementing the method and structures within the hardware component.
[0143] The systems, devices, modules, or units described in the above embodiments can be implemented by computer chips or physical entities, or by products with certain functions. A typical implementation device is a server system. Of course, this application does not exclude the possibility that, with the future development of computer technology, the computer implementing the functions of the above embodiments can be, for example, a personal computer, a laptop computer, an in-vehicle human-machine interaction device, a cellular phone, a camera phone, a smartphone, a personal digital assistant, a media player, a navigation device, an email device, a game console, a tablet computer, a wearable device, or any combination of these devices.
[0144] While one or more embodiments of this specification provide the steps of operation for the methods described in the embodiments or flowcharts, more or fewer steps may be included based on conventional or non-inventive means. The order of steps listed in the embodiments is merely one possible order of execution among many steps and does not represent the only possible order. In actual device or end product execution, the methods shown in the embodiments or drawings may be executed sequentially or in parallel (e.g., in a parallel processor or multi-threaded processing environment, or even a distributed data processing environment). The terms "comprising," "including," or any other variations thereof are intended to cover non-exclusive inclusion, such that a process, method, product, or apparatus that comprises a list of elements includes not only those elements but also other elements not expressly listed, or elements inherent to such a process, method, product, or apparatus. Without further limitations, the presence of other identical or equivalent elements in a process, method, product, or apparatus that includes said elements is not excluded. For example, the use of terms such as "first," "second," etc., is to denote names and does not indicate any particular order.
[0145] For ease of description, the above devices are described in terms of function, divided into various modules. Of course, when implementing one or more of these specifications, the functions of each module can be implemented in one or more software and / or hardware components, or a module that performs the same function can be implemented by a combination of multiple sub-modules or sub-units. The device embodiments described above are merely illustrative. For example, the division of units is only a logical functional division; in actual implementation, there may be other division methods. For example, multiple units or components may be combined or integrated into another system, or some features may be ignored or not executed. Furthermore, the coupling or direct coupling or communication connection shown or discussed may be through some interfaces, indirect coupling or communication connection between devices or units, and may be electrical, mechanical, or other forms.
[0146] This invention is described with reference to flowchart illustrations and / or block diagrams of methods, apparatus (systems), and computer program products according to embodiments of the invention. It will be understood that each block of the flowchart illustrations and / or block diagrams, and combinations of blocks in the flowchart illustrations and / or block diagrams, can be implemented by computer program instructions. These computer program instructions can be provided to a processor of a general-purpose computer, special-purpose computer, embedded processor, or other programmable data processing apparatus to produce a machine, such that the instructions, which execute via the processor of the computer or other programmable data processing apparatus, create means for implementing the functions specified in one or more blocks of the flowchart illustrations and / or one or more blocks of the block diagrams.
[0147] These computer program instructions may also be stored in a computer-readable storage medium that can direct a computer or other programmable data processing device to function in a particular manner, such that the instructions stored in the computer-readable storage medium produce an article of manufacture including instruction means that implement the functions specified in one or more flowcharts and / or one or more block diagrams.
[0148] These computer program instructions may also be loaded onto a computer or other programmable data processing apparatus to cause a series of operational steps to be performed on the computer or other programmable apparatus to produce a computer-implemented process, such that the instructions, which execute on the computer or other programmable apparatus, provide steps for implementing the functions specified in one or more flowcharts and / or one or more block diagrams.
[0149] In a typical configuration, a computing device includes one or more processors (CPU), input / output interfaces, network interfaces, and memory.
[0150] Memory may include non-persistent storage in computer-readable media, such as random access memory (RAM) and / or non-volatile memory, such as read-only memory (ROM) or flash RAM. Memory is an example of computer-readable media.
[0151] Computer-readable media, including both permanent and non-permanent, removable and non-removable media, can store information using any method or technology. Information can be computer-readable instructions, data structures, program modules, or other data. Examples of computer storage media include, but are not limited to, phase-change memory (PRAM), static random access memory (SRAM), dynamic random access memory (DRAM), other types of random access memory (RAM), read-only memory (ROM), electrically erasable programmable read-only memory (EEPROM), flash memory or other memory technologies, CD-ROM, digital versatile optical disc (DVD) or other optical storage, magnetic tape, magnetic magnetic disk storage, graphene storage or other magnetic storage devices, or any other non-transferable medium that can be used to store information accessible by a computing device. As defined herein, computer-readable media does not include transient computer-readable media, such as modulated data signals and carrier waves.
[0152] Those skilled in the art will understand that one or more embodiments of this specification can be provided as a method, system, or computer program product. Therefore, one or more embodiments of this specification may take the form of a completely hardware embodiment, a completely software embodiment, or an embodiment combining software and hardware aspects. Furthermore, one or more embodiments of this specification may take the form of a computer program product implemented on one or more computer-usable storage media (including, but not limited to, disk storage, CD-ROM, optical storage, etc.) containing computer-usable program code.
[0153] One or more embodiments of this specification can be described in the general context of computer-executable instructions, such as program modules, that are executed by a computer. Generally, program modules include routines, programs, objects, components, data structures, etc., that perform a particular task or implement a particular abstract data type. One or more embodiments of this specification can also be practiced in distributed computing environments where tasks are performed by remote processing devices connected via a communication network. In a distributed computing environment, program modules can reside in local and remote computer storage media, including storage devices.
[0154] The various embodiments in this specification are described in a progressive manner. Similar or identical parts between embodiments can be referred to mutually. Each embodiment focuses on describing the differences from other embodiments. In particular, system embodiments are basically similar to method embodiments, so the description is relatively simple; relevant parts can be referred to the descriptions in the method embodiments. In the description of this specification, the terms "one embodiment," "some embodiments," "example," "specific example," or "some examples," etc., refer to specific features, structures, materials, or characteristics described in connection with that embodiment or example, which are included in at least one embodiment or example of this specification. In this specification, the illustrative expressions of the above terms do not necessarily refer to the same embodiment or example. Furthermore, the specific features, structures, materials, or characteristics described can be combined in any suitable manner in one or more embodiments or examples. Moreover, without contradiction, those skilled in the art can combine and integrate the different embodiments or examples described in this specification and the features of different embodiments or examples.
[0155] The above description is merely an embodiment of one or more embodiments of this specification and is not intended to limit the scope of this specification. Various modifications and variations can be made to the one or more embodiments of this specification by those skilled in the art. Any modifications, equivalent substitutions, improvements, etc., made within the spirit and principles of this specification should be included within the scope of the claims. < / k3-v3> < / k2-v2> < / k1-v1> < / k3-v3> < / k2-v2> < / k1-v1> < / k3-v3> < / k2-v2> < / k1-v1> < / k3-v3> < / k2-v2> < / k1-v1>
Claims
1. A method for reading blockchain state data, applied to a storage module of a blockchain node, wherein the storage module constructs a tree-structured world state in memory, and the leaf nodes of the tree structure include the position index of the state data within a data file in a persistent storage medium; the method includes: The storage module of the blockchain node receives the instruction to look up the state key and searches for the leaf node corresponding to the state key in the tree structure in memory; Obtain the location index contained in the leaf node, where the location index points to a location within the data file in the persistent storage medium; Load the value of the data file location in the persistent storage medium pointed to by the location index into memory and read the status data therein.
2. The method as described in claim 1, wherein searching for the leaf node corresponding to the state key in the tree structure in memory includes: Starting from the root node of the tree structure, match the path of the state key segment by segment until the leaf node of the tree structure corresponding to the state key is found.
3. The method as described in claim 2, wherein matching the path of the state key segment by segment starting from the root node of the tree structure includes: Starting from the previous level tree node, match the hash of the path of the state key in sequence, and search for the next level tree node based on the hash, until the leaf node of the tree structure corresponding to the state key is found.
4. The method as described in claim 2, wherein matching the path of the state key segment by segment starting from the root node of the tree structure includes: Starting from the previous level tree node, the path keys of the state key are matched sequentially, and the next level tree node is searched based on the matched key, until the leaf node of the tree structure corresponding to the state key is found.
5. The method according to any one of claims 1-4, when there is no state data in the leaf node in memory, the position index contained in the leaf node is obtained.
6. The method according to any one of claims 1-4, when the leaf node does not exist in memory, the tree node key of the leaf node is searched from persistent storage, the value corresponding to the key is loaded into memory, and the position index is obtained from the value.
7. The method as described in claim 6, wherein the tree node key of the leaf node of the tree structure corresponds to the state key, then the step of searching for the tree node key of the leaf node from persistent storage when the leaf node does not exist in memory includes: When the leaf node does not exist in memory, the tree node key of the leaf node is searched in persistent storage based on the state key.
8. The method according to any one of claims 1-7, wherein the tree structure comprises a single-layer tree structure or a two-layer tree structure.
9. A blockchain node, the blockchain node comprising a storage module, the storage module comprising a tree construction module and persistent storage, the persistent storage medium comprising an index file and a data file; the storage module further comprising a search unit and a read unit; the leaf nodes of the tree structure comprising an index of the position of state data within the data file in the persistent storage medium; The tree-building module is used to build the world state of a tree structure in memory; The search unit receives an instruction to search for a state key, searches for the leaf node corresponding to the state key in the tree structure in memory, and obtains the location index contained in the leaf node, the location index pointing to the location in the data file in the persistent storage medium; The reading unit loads the value of the data file location in the persistent storage medium pointed to by the location index into memory and reads the status data therein.
10. The blockchain node as described in claim 9, wherein the search unit matches the path of the state key segment by segment starting from the root node of the tree structure until the leaf node of the tree structure corresponding to the state key is found.
11. The blockchain node as described in claim 10, wherein the search unit sequentially matches the hash of the path of the state key starting from the previous level tree node, and searches for the next level tree node based on the hash, until it finds the leaf node of the tree structure corresponding to the state key.
12. The blockchain node as described in claim 10, wherein the search unit sequentially matches the key of the path of the state key starting from the previous level tree node, and searches the next level tree node according to the matched key, until the leaf node of the tree structure corresponding to the state key is found.
13. The blockchain node as described in any one of claims 9-12, when there is no state data in the leaf node in memory, obtains the position index contained in the leaf node.
14. In any one of claims 9-12, when the leaf node does not exist in memory, the tree node key of the leaf node is searched in the index file in persistent storage, the value in the data file corresponding to the key is loaded into memory, and the position index is obtained from the value.
15. In the blockchain node of claim 14, where the tree node key of the leaf node in the tree structure corresponds to the state key, then when the leaf node does not exist in memory, the tree node key of the leaf node is retrieved from persistent storage. When the leaf node does not exist in memory, the search unit searches for the tree node key of the leaf node in the persistently stored index file based on the status key.
16. The blockchain node as described in any one of claims 9-15, wherein the tree structure comprises a single-layer tree structure or a two-layer tree structure.
Citation Information
Patent Citations
Block chain data storage method and device and electronic equipment
CN115221176A
Method for creating account in block chain and block chain node
CN115982781A
Block chain-based state data storage method and device
CN116610670A