Tree-structured world state storage method, recovery method, and computer device

By employing a tree-structured storage method in blockchain technology, which converts tree nodes into memory pages and generates basic and incremental pages, the problems of high data redundancy and low recovery efficiency are solved, achieving more efficient storage and faster state recovery.

WO2026016332A1PCT designated stage Publication Date: 2026-01-22ANT BLOCKCHAIN TECHNOLOGY (SHANGHAI) CO LTD

Patent Information

Application Number
PCT/CN2024/128760
Authority / Receiving Office
WO · WO
Patent Type
Applications
Current Assignee / Owner
Priority Date
2024-07-19
Filing Date
2024-10-31
Publication Date
2026-01-22

AI Technical Summary

Technical Problem

Existing blockchain technology suffers from high data redundancy, large storage overhead, and low efficiency in restoring any version of the state when storing and restoring the world state.

Method used

A tree-structured storage method is adopted, which converts generated or updated tree nodes into memory pages, and generates base pages and incremental pages based on logical pages of consecutive versions. These are all persisted in a database, and during recovery, the base pages and incremental pages are loaded into memory according to the version order.

Benefits of technology

It reduces data redundancy, decreases storage overhead, and improves the efficiency and speed of restoring any version of the state.

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN2024128760_22012026_PF_FP_ABST
    Figure CN2024128760_22012026_PF_FP_ABST
Patent Text Reader

Abstract

A tree-structured world state storage method, a recovery method, and a computer device. The storage method comprises: with respect to generated / updated tree nodes, according to a logical page structure obtained by division, generating corresponding memory pages, the memory pages being used for representing content of all corresponding tree nodes in the logical pages, wherein the logical pages are results obtained by aggregating several upper and lower adjacent tree nodes according to a node association relationship of the tree structure, each logical page contains at least one tree node, and the tree nodes in different logical pages are mutually exclusive; on the basis of changes in the contents of all the tree nodes in consecutive versions of the logical pages, generating base pages and delta pages; and persisting the base pages and the delta pages in one database without distinguishing between a currentDB and a historyDB.
Need to check novelty before this filing date? Find Prior Art

Description

A tree structure world state storage method, recovery method and computer device

[0001] The present application claims priority from the Chinese patent application No. 2024109806638 filed on July 19, 2024, and entitled "A tree structure world state storage method, recovery method and computer device", the content of which is incorporated herein by reference in its entirety. TECHNICAL FIELD

[0002] The embodiments of the present specification belong to the technical field of blockchain technology, and particularly relate to a tree structure world state storage method, recovery method and computer device. BACKGROUND

[0003] Blockchain is a new application mode of distributed data storage, peer-to-peer transmission, consensus mechanism, encryption algorithm and other computer technologies. In a blockchain system, data blocks are combined into a chain-like data structure in a sequential manner according to time sequence, and are guaranteed to be tamper-proof and unforgeable by cryptography. Due to the characteristics of decentralization, information tamper-proofing, autonomy and other characteristics, blockchain has also received more and more attention and application.

[0004] SUMMARY

[0005] The purpose of the present application is to provide a tree structure world state storage method, recovery method and computer device, comprising:

[0006] A tree structure world state storage method, comprising:

[0007] The generated / updated tree node is used to generate a corresponding memory page according to the divided logical page structure, and the memory page is used to represent the content of all tree nodes in the logical page; the logical page is the result of aggregating a plurality of adjacent tree nodes according to the node association relationship of the tree structure, and each logical page contains at least one tree node, and each logical page contains different tree nodes;

[0008] Based on the changes of the contents of all tree nodes in the continuous version logical page, a base page and a delta page are generated;

[0009] The base page and the delta page are persisted in a database without distinguishing currentDB and historyDB.

[0010] A method for recovering any version of the world state from a stored database, comprising:

[0011] Reading the version to be recovered;

[0012] reading a base page of the same version as the recovery version from the database;

[0013] if a base page of the same version as the recovery version is read from the database, loading the base page of the recovery version from the database to memory to obtain a memory page;

[0014] if a base page of the same version as the recovery version is not read from the database, loading a base page of a maximum version not greater than the recovery version and of a base page type from the database to memory, and loading an incremental page of a minimum version not less than the recovery version and of an incremental page type from the database to memory after the version of the base page is loaded; playing back the loaded base page and incremental page according to the page type and version order to obtain a memory page of the recovery version;

[0015] for a memory page containing a leaf node, reading a state in the leaf node to memory.

[0016] A computer device comprises:

[0017] a processor;

[0018] and a memory, wherein the memory stores a program, and when the processor executes the program, the operations of any one of the above are performed.

[0019] In the scheme, when data is written to a disk, the historyDB and the currentDB are no longer distinguished, and the base page and the incremental page are written to one database. In this way, the currentDB and the historyDB are not used as in the prior art, so that the redundancy of data can be reduced, the storage overhead can be reduced, and the scheme that only the currentDB is retained and the historyDB is not maintained in the prior art makes it faster and more efficient to restore the state of any version. BRIEF DESCRIPTION OF DRAWINGS

[0020] In order to more clearly illustrate the technical solutions in the embodiments of the present specification, the drawings needed in the embodiment description will be briefly introduced below. Obviously, the drawings in the following description are only some embodiments described in the present specification, and other drawings can be obtained by those skilled in the art without creative labor.

[0021] FIG. 1 is a schematic diagram of deploying a smart contract in an embodiment;

[0022] FIG. 2 is a schematic diagram of calling a smart contract in an embodiment;

[0023] FIG. 3 is a schematic diagram of a block storage structure in an embodiment;

[0024] Figure 4 is a diagram of a block storage structure in an embodiment;

[0025] Figure 5 is a diagram of an MPT tree in an embodiment;

[0026] Figure 6 is a diagram of modules involved in a transaction processing process and the relationship of CPU, memory and disk in an embodiment;

[0027] Figure 7 is a diagram of modules involved in a transaction processing process and the relationship of CPU, memory and disk in an embodiment;

[0028] Figure 8 is a diagram of logical relationship of state database in an embodiment;

[0029] Figure 9 is a flowchart of reading state data in an embodiment;

[0030] Figure 10 is a diagram of reading state data in an embodiment in connection with a tree structure;

[0031] Figure 11 is a diagram of reading state data in an embodiment in connection with a tree structure;

[0032] Figure 12 is a diagram of reading state data in an embodiment in connection with a tree structure;

[0033] Figure 13 is a diagram of reading state data in an embodiment in connection with a tree structure;

[0034] Figure 14 is a diagram of reading state data in an embodiment in connection with a tree structure;

[0035] Figure 15 is a diagram of a block storage structure in an embodiment;

[0036] Figure 16 is a diagram of a block storage structure in an embodiment;

[0037] Figure 17 is a diagram of a block storage structure in an embodiment;

[0038] Figure 18 is a diagram of a block storage structure in an embodiment;

[0039] Figure 19 is a diagram of a block storage structure in an embodiment;

[0040] Figure 20 is a diagram of a block storage structure in an embodiment. DETAILED DESCRIPTION

[0041] In order for those skilled in the art to better understand the technical solutions in the specification, the technical solutions in the specification will be clearly and completely described below in combination with the drawings in the specification. Obviously, the described embodiments are only a part of the embodiments of the specification, not all the embodiments. Based on the embodiments in the specification, all other embodiments obtained by those of ordinary skill in the art without creative labor should be within the scope of protection of the specification.

[0042] Blockchain is generally divided into three types: public chain (Public Blockchain), private chain (Private Blockchain) and consortium chain (Consortium Blockchain). In addition, there are various combinations, such as private chain + consortium chain, consortium chain + public chain, and different combination forms. Among them, the highest degree of decentralization is the public chain. The public chain is represented by Bitcoin and Ethereum. Participants who join the public chain can read data records on the chain, participate in transactions, and compete for the right to account for new blocks, etc. Moreover, participants (represented by nodes on the blockchain) can freely join and exit the network and perform related operations. The private chain is the opposite. The write permission of the network is controlled by an organization or an institution, and the data reading permission is subject to the organization's regulations. Simply put, the private chain can be a weakly centralized system with strict restrictions and few participating nodes. This type of blockchain is more suitable for use within a specific institution. Consortium chain is a blockchain between public chain and private chain, which can achieve "partial decentralization". Each node in the consortium chain usually has a corresponding entity or organization; participants join the network by authorization and form an interest-related consortium to jointly maintain the operation of the blockchain.

[0043] Whether it is a public chain, a private chain or a consortium chain, in addition to supporting the transfer of native assets on the blockchain between accounts, such as transferring Bitcoin, Ethereum, etc., it can also provide the function of smart contract. The smart contract on the blockchain is a contract that can be triggered by a transaction to execute on the blockchain system. The smart contract can be defined in the form of code.

[0044] Taking Ethereum as an example, it supports users to create and call some complex logic in the Ethereum network, which is the biggest challenge of Ethereum blockchain technology compared with Bitcoin. The core of Ethereum as a programmable blockchain is Ethereum Virtual Machine (EVM), and each Ethereum node can run EVM. EVM is a Turing-complete virtual machine, which means that various complex logics can be implemented through it. The user publishes and calls a smart contract in Ethereum is to run on EVM. In fact, the virtual machine directly runs the virtual machine code (virtual machine bytecode, hereinafter referred to as "bytecode"). The smart contract deployed on the blockchain can be in the form of bytecode.

[0045] For example, as shown in FIG. 1, after Bob sends a transaction containing the information for creating a smart contract to the Ethereum network, the EVM of node 1 can execute the transaction and generate a corresponding contract instance. The "0x6f8ae93..." in FIG. 1 represents the address of the contract, the data field of the transaction can save the bytecode, and the to field of the transaction is an empty account. After the nodes reach an agreement through the consensus mechanism, the contract is successfully created, and subsequent users can call the contract.

[0046] After the contract is created, a contract account corresponding to the smart contract is generated on the blockchain, and has a specific address. The contract code and account storage will be saved in the contract account. The behavior of the smart contract is controlled by the contract code, and the account storage of the smart contract saves the state of the contract. In other words, the smart contract causes the generation of a virtual account containing the contract code and the account storage (Storage) on the blockchain.

[0047] As mentioned above, the data field of the transaction containing the creation of the smart contract can save the bytecode of the smart contract. The bytecode is composed of a series of bytes, and each byte can identify an operation. Based on development efficiency, readability and other aspects, the developer can not directly write the bytecode, but can choose a high-level language to write the smart contract code. The smart contract code written in a high-level language is compiled by a compiler to generate bytecode, and the bytecode can be deployed to the blockchain. Ethereum supports many high-level languages, such as Solidity, Serpent, LLL language, etc.

[0048] Taking the Solidity language as an example, the contract written in the Solidity language is very similar to the class (Class) in the object-oriented programming language. Multiple members can be declared in a contract, including state variables, functions, function modifiers, events, etc. The state variable is a value stored in the account storage of the smart contract, which is used to save the state of the contract.

[0049] The following is a code example 1 of a simple smart contract written in the Solidity language:

[0050] In addition, as shown in FIG. 2, still taking Ethereum as an example, after Bob sends a transaction containing the information of calling the smart contract to the Ethereum network, the EVM of node 1 can execute the transaction and generate the corresponding contract instance. The from field of the transaction in FIG. 2 is the address of the account initiating the call to the smart contract, the "0x6f8ae93..." in the to field represents the address of the called smart contract, and the data field of the transaction saves the method and parameters of calling the smart contract. In addition, the value field can also be included to represent the value of the ether in the transaction. After calling the smart contract, the value of storedData can change. Subsequently, a client can view the current value of storedData through a certain blockchain node (for example, node 6 in FIG. 2).

[0051] The smart contract can be executed independently in a specified manner in each node of the blockchain network, and all execution records and data are saved on the blockchain, so when such a transaction is completed, the transaction voucher is saved on the blockchain and cannot be tampered with or lost.

[0052] As mentioned earlier, storedData in the above example is a state variable, which is stored in the account storage of the smart contract. In various blockchain networks introducing smart contracts, for example, Ethereum, an account generally includes two types:

[0053] Contract account: stores the executed smart contract code and the state value in the smart contract code, which can usually only be activated by calling an external account;

[0054] Externally owned account: user's account, for example, Ethereum owner account.

[0055] The design of external accounts and contract accounts is actually a mapping of account addresses to account states. The state of an account generally includes fields such as Nonce, Balance, Storage root, CodeHash, etc. Nonce and Balance exist in both external accounts and contract accounts. CodeHash and Storage root attributes are generally only valid on contract accounts.

[0056] Nonce: 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.

[0057] Balance: the number of ethers owned by this address.

[0058] Storage root: The hash of a root node of an MPT tree that organizes the storage of state variables of a contract account.

[0059] CodeHash: The hash of the smart contract code. For a contract account, this is the hash of the smart contract; for an external account, since no smart contract is included, the CodeHash field can generally be an empty string / 0 string.

[0060] MPT stands for Merkle Patricia Tree, which is a tree structure that combines the Merkle Tree and Patricia Tree (a more space-efficient Trie tree). The Merkle Tree algorithm calculates a Hash value for each transaction, then connects them two by two to calculate the Hash again, all the way to the top layer of the Merkle root. Ethereum uses an improved MPT tree, such as a 16-ary tree structure, which is also commonly referred to as an MPT tree.

[0061] The data structure of the Ethereum MPT tree includes a state tree (state trie). The state tree contains the key-value pairs (k-v) of the storage content corresponding to each account in the Ethereum network. The "key" in the state tree can be a 160-bit identifier (such as a part of the hash value of the Ethereum account address or address, hereinafter referred to as account address), which is distributed in the storage from the root node of the state tree to the leaf node. The "value" in the state tree is generated by encoding the information of the Ethereum account (using the Recursive-Length Prefix encoding (RLP) method). As mentioned earlier, for an external account, the value includes nonce and balance; for a contract account, the value includes nonce, balance, codehash, and storageroot.

[0062] A contract account is used to store the state related to a smart contract. After a smart contract is deployed on a blockchain, a corresponding contract account is generated. The contract account generally has some states, which are defined by the state variables in the smart contract and generate new values when the smart contract is created and executed. The smart contract generally refers to a contract defined in the form of code in a blockchain environment, which can automatically execute clauses. Once an event triggers the clauses in the contract (satisfies the execution condition), the code can be automatically executed. In the blockchain, the state related to the contract is saved in the storage trie, and the hash value of the root node of the storage trie is stored in the storage root, so that all states of the contract are locked to the contract account through hash. The storage trie is also an MPT tree structure, which stores the key-value mapping of state address to state value. The address of a state is stored in the leaf node of the storage trie tree after the information in the leaf node is arranged in sequence, and the value of the state is stored in the leaf node.

[0063] In some blockchain data storage as shown in FIG. 3, the block header of each block includes several fields, such as the previous block hash previous_Hash (Prev Hash in the figure), a nonce Nonce (in some blockchain systems, this nonce is not a random number, or in some blockchain systems, the nonce in the block header is not enabled), a timestamp Timestamp, a block number Block Num, a state root hash State_Root, a transaction root hash Transaction_Root, a receipt root hash Receipt_Root, etc. Among them, the Prev Hash in the block header of the next block (such as block N+1) points to the previous block (such as block N), which is the hash value of the previous block. In this way, the previous block is locked by the next block through the block header on the blockchain. Among them, State_Root, Transaction_Root and Receipt_Root lock the state set, the transaction set and the receipt set respectively. The state set, the transaction set and the receipt set are organized in the form of a tree to organize the state, the transaction and the receipt respectively. Generally, it can be the same tree structure or different tree structures. For example, in Ethereum, the same MPT structure is used. In some tree structures including the state set of the smart contract in Ethereum and the like, two levels of MPT structures are included: the leaf nodes of the upper level of the MPT structure include two types of external accounts and contract accounts; each contract account in it includes the lower level of the MPT structure, and the leaf nodes of the lower level include the values of the states in the contract account.

[0064] Figure 4 is a structural diagram of a blockchain data storage. Still taking Ethereum as an example, as shown in 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, i.e., state_root points to a state tree state trie in the form of MPT. The root node of this MPT tree is generally an extension node (Extension Node) or a branch node (Branch Node), and state_root generally stores the hash value of this root node. The root node can be connected to one or more layers of Extension Node / Branch Node, and these multiple layers of tree nodes can be collectively referred to as Internal Node. A part of the value in each node from the root node of this MPT to the leaf node can be concatenated in order to form an account address as a key, and the account information stored in the leaf node is the value corresponding to this account address, so as to form a key-value pair. This key can also be a part of the hash value of the account address (the hash algorithm can be, for example, sha3 algorithm), and the value stored can be rlp(Account), i.e., the rlp encoding of the account information. The account information is a four-tuple of [nonce, balance, storageRoot, codeHash]. As described above, for an external account, generally only nonce and balance are stored, and storageRoot and codeHash fields store empty strings / strings of all 0s by default. That is, an external account does not store a contract, nor does it store the state variables generated after the execution of the contract. A contract account generally includes Nonce, Balance, Storage root, and CodeHash. Nonce is the transaction counter of the contract account; Balance is the account balance; Storage root corresponds to another MPT, and through Storage root, the information of the state related to the contract can be linked; and CodeHash is the hash value of the contract code. Whether it is an external account or a contract account, the account information is generally located in a separate leaf node (Leaf Node). From the Extension Node / Branch Node of the root node to the Leaf Node of each account, there can be several branch nodes and extension nodes in between.

[0065] The state trie can be a tree in the form of MPT, typically a 16-ary tree, i.e. each level can have at most 16 child nodes. For an Extension Node, which is used to store common prefix, it typically has 1 child node, which can be a Branch Node. For a Branch Node, it can have at most 16 child nodes, which can include Extension Nodes and / or Leaf Nodes.

[0066] For a contract account in the state trie, its storage_Root points to another tree in the form of MPT, which stores data of state variables involved in the execution of the contract. The MPT form tree pointed by the storage_Root is a Storage Trie, i.e. the hash value of the root node of the Storage Trie. Typically, the Storage Trie also stores key-value pairs. The key indicates the address of a state variable, which can be the result of processing the location of the state variable declaration (value counted from 0) by certain rules, e.g. sha3(location of state variable declaration), or sha3(contract name + location of state variable declaration). The value is used to store the value of the state variable (e.g. RLP encoded value). The part of data stored on the path from the root node to the leaf node forms the key, and the value is stored in the leaf node. As mentioned before, the Storage trie can also be a tree in the form of MPT, typically a 16-ary tree, i.e. for a Branch Node, it can have at most 16 child nodes, which can include Extension Nodes and / or Leaf Nodes. For an Extension Node, it typically can have 1 child node, which can be a Branch Node or a Leaf Node.

[0067] For example, Leaf Node Account P in state Trie in Fig. 4, which is a contract account, its Storage Root locks all the states in the contract storage. These states are organized as an MPT tree, and the tree structure is the linked Storage trie of the Storage Root. For example, Leaf Node State Variable N in the linked Storage trie, for example, the value of storedData in the aforementioned contract code example, its key is sha3(the declaration position of storedData, i.e., the second line of the code), and its value is s (for brevity, the encoding format of the value is omitted here, for example, RLP, and the like will not be repeated). The value of the key is distributed in the root node to the leaf node (i.e., Leaf Node Variable N) of the storage trie.

[0068] For another example, Leaf Node Account C in state Trie in Fig. 4, which is an external account, its key is sha3(Address C), i.e., the hash value of the address of account C (the hash algorithm uses the sha3 algorithm, for example), and its stored value value can be (Account). As described above, since Account C is an external account, its account information is nonce and balance (codehash and storage root are omitted here, and the like below). For example, an external account with nonce 20 and balance 4550, Leaf Node State Variable C stores nonce = 20 and balance = 4550 in this leaf node. The address of Account C is the key, and the value is distributed in the root node to the leaf node (i.e., Leaf Node Variable C) of the state Trie.

[0069] These states, including the k-v of the external account and the k-v of the contract account, are finally stored in the database. The storage in the database does not directly store the states of these accounts, i.e., does not directly store the k-v of these accounts, but stores the k-v value of each tree node itself.

[0070] As shown in the example of FIG. 5, in the MPT structure of the previous level, for leaf node Al, the key of the leaf node is sequentially composed of a7 in the shared nibble of root node A8 (Extension Node) - slot 1 of intermediate node A7 (Branch Node) - 1335 of key-end in leaf node Al, i.e., a711335, in which Balance = 45.0 ETH and Nonce = nl are stored. For leaf node A2, the key of the leaf node is sequentially composed of a7 in the shared nibble of root node A8 (Extension Node) - slot 7 of intermediate node A7 (Branch Node) - d3 in the shared nibbles of node A6 (Extension Node) - slot 3 of intermediate node A5 (Branch Node) - 7 of key-end in leaf node A2, i.e., a77d337, in which Balance = 1.00 WEI and Nonce = n2 are stored. For leaf node A3, the key of the leaf node is sequentially composed of a7 in the shared nibble of root node A8 (Extension Node) - slot f of intermediate node A7 (Branch Node) - 9365 of key-end in leaf node A3, i.e., a7f9365, in which Balance = 1.1 ETH and Nonce = n3 are stored. For leaf node A4, the key of the leaf node is sequentially composed of a7 in the shared nibble of root node A8 (Extension Node) - slot 7 of intermediate node A7 (Branch Node) - d3 in the shared nibbles of node A6 (Extension Node) - slot 9 of intermediate node A5 (Branch Node) - 7 of key-end in leaf node A4, i.e., a77d397, in which Balance = 0.12 ETH, Nonce = n4, and CodeHash = cl are stored, and Storage root = sl. sl can be H(A10), i.e., the hash of root node A10 of the next level tree. Among them, the leaf nodes of Al, A2, and A3 store the information of external accounts, and the leaf node of A4 stores the information of a contract account. For a contract account, it contains the next level MPT, which constitutes a Storage Trie, used to store the state variables in the contract account.

[0071] As shown in the example of FIG. 5, in the next level of MPT structure, for leaf node A11, the key of the leaf node is composed of the slot 3 in the root node A10 (Branch Node) and the key-end 35b2e4 in the leaf node A11, i.e. 335b2e4, and the "Zhang San_A=20" is stored in the leaf node, for example, indicating that the share of the A type digital asset defined in the contract belonging to Zhang San is 20, i.e. the balance of the A type asset of Zhang San is 20. For leaf node A12, the key of the leaf node is composed of the slot 7 in the root node A10 (Branch Node) and the key-end c25988 in the leaf node A12, i.e. 7c25988, and the "Li Si_B=20" is stored in the leaf node, for example, indicating that the share of the B type digital asset defined in the contract belonging to Li Si is 50, i.e. the balance of the B type asset of Li Si is 50. For leaf node A15, the key of the leaf node is composed of the slot f in the root node A10 (Branch Node), the shared nibble a in the intermediate node A13 (Extension Node), the slot 6 in the intermediate node A14 (Branch Node) and the key-end be33 in the leaf node A15, i.e. fa6be33, and the "storedData=s" is stored in the leaf node. For leaf node A16, the key of the leaf node is composed of the slot f in the root node A10 (Branch Node), the shared nibble a in the intermediate node A13 (Extension Node), the slot 9 in the intermediate node A14 (Branch Node) and the key-end 9365 in the leaf node A16, i.e. fa99365, and the "Wang Wu_A=35" is stored in the leaf node, for example, indicating that the share of the A type digital asset defined in the contract belonging to Wang Wu is 35, i.e. the balance of the A type asset of Wang Wu is 35.

[0072] In the node composition of the above MPT tree, the prefix is used to represent the type of tree node, 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.

[0073] In the above node structure, the hash value of the overall content of the next tree node is filled into the corresponding position of the previous tree node. In the database, the key-value mapping of each tree node is actually stored, where the value includes the content stored in the tree node, and the corresponding key is the hash value of the overall content of the tree node. In this way, the actual tree node k-v stored in the database is as follows:

[0074] Table 1, actual tree node k-v stored in the database

[0075] In the above table 1, H() represents hash calculation. In this way, the hash value of the next tree node is anchored in the previous tree node. Through such layer-by-layer hash, the root hash of the entire state trie tree is obtained, and the root hash is locked into the state root field of the block header.

[0076] In some blockchain systems, the code of the blockchain platform can include a P2P (Peer to Peer) module, a consensus module, an execution module and a storage module. P2P is a way of organizing computer networks, unlike the common web network, P2P is decentralized and decentralized. The P2P module can complete the distributed propagation of data. For a blockchain node, it can propagate and receive receipts in a peer-to-peer manner through the P2P module. Different participants can establish a distributed blockchain network through the deployed nodes. The ledger constructed by the chain block structure is saved on each node (or most nodes, such as consensus nodes) in the distributed blockchain network, which is also called a decentralized (or called multi-centralized) distributed ledger. Such a blockchain system needs to solve the consistency and correctness of the ledger data on each node of the decentralized (or multi-centralized) distributed ledger. Each node runs the same blockchain platform program, and under certain fault tolerance requirements, the consensus module can ensure that all loyal nodes have the same transaction, so that all loyal nodes have the same execution result of the same transaction, and the transaction and execution result are packaged to generate a block. The current mainstream consensus mechanism includes: Proof of Work (POW), Proof of Stake (POS), Delegated Proof of Stake (DPOS), Practical Byzantine Fault Tolerance (PBFT) algorithm, HoneyBadgerBFT algorithm, etc. The consensus module can also generate the timestamp of the block corresponding to the current transaction set during the consensus process. The execution module can execute transactions, including ordinary transfer transactions and transactions involving contracts, which can be before or after the consensus module completes the consensus. For transactions involving contracts, the execution module can introduce a virtual machine to execute the code of the smart contract, such as Ethereum Virtual Machine (EVM), so as to shield the differences in hardware configuration and software environment of each node through EVM, so as to ensure that the process and result of executing the smart contract on each node are the same, and through the sandbox environment, the execution of the smart contract avoids affecting the blockchain platform code, other programs or operating system on the host. For a case of a consortium chain, the transaction content and transaction order in a transaction set can be determined by the consensus module between the nodes, and then the deterministic transaction set of the consensus result is output to the execution module. The execution module generates an execution result by executing ordinary transfer transactions / transactions involving contracts, and sends it to the storage module. The storage module can be responsible for storing the execution result in the persistent storage medium of the node local.

[0077] As shown in FIG. 6, one blockchain node physically includes CPU, memory and disk, etc. The blockchain platform code executed by this blockchain node can include P2P module, consensus module, execution module and storage module. The functions of P2P module, consensus module and execution module generally need the participation of CPU and memory. The storage module can include tree construction module, block header generation module, WAL (Write Ahead Log) module and state database module. Among them, the tree construction module is used to construct a tree (such as MPT tree) based on the state k-v input by the execution module, such as the state trie and storage trie described above, so as to obtain the k-v of the tree node, which generally needs the participation of CPU and memory. The block header generation module is used to generate the block header according to the root node of the tree constructed by the tree construction module and other data (such as the hash of the previous block, timestamp, block number, etc.), which generally needs the participation of CPU and memory. The WAL module is used to persistently store the leaf node k-v of the tree generated by the tree construction module before the leaf node k-v is written into the state database module, so as to prevent data loss due to power failure, etc. during the process of writing the leaf node k-v of the tree generated by the tree construction module into the state database module, and to recover the data when such a situation occurs, which generally needs the participation of CPU, memory and disk. The state database module is used to store the tree node k-v constructed by the tree construction module in the persistent storage device, such as Table 1. Since the tree node data will eventually be written to the persistent storage medium (such as the disk in the figure), the state database module generally needs the participation of disk in addition to CPU and memory.

[0078] From the storage structure, the above Merkle tree structure, such as the MPT of Ethereum, the SMT (Sparse Merkle Tree) of Libra (similar to MPT), can be located in the tree construction module in the form of the corresponding relationship in the above table 1 and stored in the memory. Among them, the upper Merkle tree is a prefix tree (dictionary tree), which can realize the organization of data and obtain a unique Merkle root for the organized data. The leaf node can save the state Value, and the root node to the intermediate node to the leaf node realizes the lexicographic index of the state key. These tree nodes are encoded as Key according to certain rules, and their contents are encoded as Value, and finally stored in the lower database. The database mostly adopts the NoSQL Key-Value DB (DataBase; Key-Value DB is also referred to as KVDB) of the LSM (Log-Structured Merge-Tree) structure, which is located in the state database module and finally saved in the disk. Specifically, the database is, for example, the levelDB of Ethereum and the RocksDB of Libra. Both of these two KVDBs are based on the LSM storage engine.

[0079] The LSM storage engine is a layered, ordered and disk-oriented storage engine, which draws on the characteristics of Log continuous appending (rather than modification), and the core idea is to fully utilize the characteristics that the sequential writing of disk batch is much more efficient than random writing, and abandon part of the reading efficiency to maximize the writing operation efficiency. Generally speaking, the use mode that maximizes the characteristics of the disk is to read or write a fixed size of data at a time, and to reduce random addressing operations as much as possible. The design idea of LSM is based on the characteristics of the disk, and assumes that the memory is sufficient, and does not need to write data to the disk every time there is data update, but first resides the latest data in the memory, and when the data volume accumulates to be enough, the data in the memory is merged with the data in the disk in the way of merge sorting, and is appended to the disk in batches.

[0080] The storage process of the state data module is further described below with reference to FIG. 7. After the tree node k-v data generated by the tree construction module is sent to the storage module, the k-v data is first written in the WAL in an append-only manner and stored on the disk. Then, the tree node k-v data is transmitted to the state database module. As described above, writing in the WAL first can prevent data loss in the process of writing the tree node k-v data generated by the tree construction module into the state database module due to power failure or the like, and restore the data when such a situation occurs. After receiving the tree node k-v data, the state database module first stores the data in the memory, which can be a MemTable in the memory. The MemTable can provide concurrent read and write operations. There can be multiple MemTables in the memory. When the amount of data in the MemTable reaches a certain threshold, for example, 256 MB, the data in the MemTable can be flushed to the disk. In order to avoid the operation of writing the MemTable from causing congestion to the flushing, the MemTable is converted into an Immutable Memtable, that is, the Immutable Memtable is set to read-only, and a new MemTable is generated to receive newly transmitted tree node k-v data. The new MemTable can provide concurrent read and write operations (e.g., the New MemTable in the figure). The storage engine writes the data in the Immutable MemTable to the disk.

[0081] In the disk, the KVDB stores a plurality of SST (Sorted String Table, SSTable) files in multiple levels. The SST is derived from a paper on Google Bigtable. BigTable is a distributed data storage system designed by Google to handle massive amounts of data in a non-relational database. The SST can be used for storage of internal data files of Bigtable and is a high-efficiency key-value type file storage format. The content stored in the persistent storage medium can also be referred to as a file.

[0082] SSTs can include multiple levels, for example, 3 levels, 4 levels, 5 levels, 6 levels, 7 levels or more. In Figure 7, the case of 3 levels is shown, i.e., level 0, level 1, level 2. Generally, the total capacity of SSTs of a previous level is significantly smaller than the next level. As an example, the total capacity of SSTs of level 0 is 1 GB, the total capacity of SSTs of level 1 is 10 GB, and the total capacity of SSTs of level 2 is 100 GB. Assume the capacity of MemTable is 256 MB. The tree nodes k-v corresponding to one or more blocks can be written into the build tree module, and then written into MemTable. After the tree k-v corresponding to one or more blocks is written into MemTable, the space occupancy of MemTable can reach 256 MB. Then, this MemTable is converted into Immutable MemTable, and the data in Immutable MemTable can be flushed to disk. Specifically, the data in MemTable can be flushed to SSTs of level 0 on disk. On the other hand, as described above, a new MemTable is generated to receive new incoming tree nodes k-v, and to provide concurrent read and write operations.

[0083] As described above, in the disk storage of each level, i.e., in the disk storage of each level, a plurality of SST files can be included. The kv stored in the SSTs of level 1 and lower levels are generally stored in order of key, and the key values in different SSTs of the same level also have a size relationship and are not repeated. For example, level 1 includes 3 SSTs, the left SST 11 includes 1000 k-v, for example, <k1-v1> <k2-v2> <k3-v3>...<k 1000 -v 1000 >, and arranged in ascending order of k, for example, k1=10b43c032a46, k2=1118d46f41e1, k3=1b44942a3d6e,..., k 1000 =2018df9326a7. It can be seen that the left SST 11 contains k1<k2<k3<...<k 1000 , but k1, k2, k3,... k 1000 are not necessarily continuous. Similarly, the middle SST 12 contains, for example, 800 k-v, <k1-v1> <k2-v2> <k3-v3>... <k 800 -v 800 > and arrange them in ascending order of k, for example, k1=21a514c0a7e1, k2=21b46b994214, k3=21b489571b6d, ..., k 800 =284a5df3fca7. It can be seen that the middle SST... 12 It contains k1 < k2 < k3 < ... < k 800 However, similarly, k1, k2, k3, ... k 800 They are not necessarily consecutive. Similarly, the SST on the right... 13 For example, it includes 1100 kV. <k1-v1> <k2-v2> <k3-v3>... <k 1100 -v 1100 > where k is arranged in ascending order, for example k1=3a5e55ac3fe1, k2=3a5e55ac3fe2, k3=3afb8ed31526, ..., k 1100 =400a51ef1405. It can be seen that the SST on the right... 13 It contains k1 < k2 < k3 < ... < k 1100 However, similarly, k1, k2, k3, ... k 1100 They are not necessarily continuous. Furthermore, overall, the left SST... 11 The minimum value of k is less than the left-hand side SST. 11 The maximum value of k is less than the middle SST. 12 The minimum value of k < the middle SST 12 The maximum value of k is less than the right-hand side SST. 13 The minimum value of k is less than the SST on the right. 13 The maximum value of k. Level 2, Level 3... are similar, that is, within each SST in each level, there is a size order relationship in terms of the value of k, and among multiple SSTs in each level, there is a size relationship in terms of the range of k.

[0084] 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 the SST on the left side of Level 0 is updated. 01 Once the space is full, it can then be written to the SST on the right side of Level 0 in a similar manner. 02 Although the k-v written by a single Immutable MemTable write in Level 0 in a certain SST is sorted, the k-v sets written by different Immutable MemTable writes in the same SST in Level 0 are generally not sorted by size, and the k-v between different SSTs (e.g. left and right SSTs) are also not sorted by size, i.e. the ranges of k in the left and right SSTs in Level 0 can have intersections / overlaps. Similarly, the k-v written in a SST in Level 0 can be written by multiple MemTable stores, and the ranges of k-v in the process of multiple MemTable stores generally have overlaps, so the multiple k-v stored in each SST in Level 0 generally also have no specific order, and the SSTs in Level 0 also generally have no specific range order. Of course, if a SST in Level 0 is written by a single Immutable MemTable write, since the Immutable MemTable sorts the k-v when writing in the SST, the k-v stored in the SST is also sorted by k.

[0085] Further, when the storage capacity of Level 0 reaches or approaches the upper limit, a process called "compaction" is used to write the data in Level 0 to Level 1. In this compaction process, the k-v in each SST in Level 0 and the k-v in some or all SSTs in Level 1 can be first transferred to memory, and then written to the SST in Level 1 after sorting in memory. Since sorting is performed in the process of compaction, the SST in Level 1 has a size order relationship in the value of k, and the multiple SSTs in Level 1 have a size relationship in the range of k. In other words, in each SST in Level 1, the k-v is sorted by k, and the multiple SSTs in Level 1 are sorted by the range of k. <k1-v1> <k2-v2> <k3-v3>... <k n -v n > are arranged in a way that k1 < k2 < k3 <... < k n , and k1, k2, k3,... k n are not necessarily continuous. Moreover, overall, for two adjacent SSTs, the minimum value of k of the left SST < the maximum value of k of the left SST < the minimum value of k of the right SST < the maximum value of k of the right SST. This is shown in Figure 8.

[0086] During the compaction process, the k-v in each SST in Level 0 and the k-v in some SSTs in Level 1, which have range overlap with the k-v in Level 0, i.e. the SSTs in Level 1 which have range overlap with the k-v in each SST in Level 0, can be transferred into memory to complete sorting. Specifically, for example, in the above example, Level 1 includes three SSTs, SST 11 , SST 12 and SST 13 . The range of keys in SST 11 is 10b43c032a46 ~ 2018df9326a7, the range of keys in SST 12 is 21a514c0a7e1 ~ 284a5df3fca7, and the range of keys in SST 13 is 3a5e55ac3fe1 ~ 400a51ef1405. For example, the range of keys in each SST in Level 0 is 18c49a405e32 ~ 24d35f39ab56. It can be seen that SST 11 and SST 12 have range overlap with the k-v in Level 0. Thus, during the compaction process, the k-v in each SST in Level 0 and the k-v in SST 11 , SST 12 in Level 1 can be transferred into memory to complete sorting, and then the sorted results are written into the SSTs in Level 1.

[0087] Similarly, when the storage capacity of Level 1 reaches the upper limit, the data in Level 1 is written into Level 2 through the compaction process. Similarly, in this compaction process, the k-v in each SST in Level 1 and the k-v in some or all SSTs in Level 2 can be first transferred into the memory, and after sorting in the memory, they are written into the SST in Level 2. Similarly, if there is Level 3 below Level 2, when the storage capacity of Level 2 reaches the upper limit, the data in Level 2 is written into Level 3 through the compaction process. Similarly, in this compaction process, the k-v in each SST in Level 2 and the k-v in some or all SSTs in Level 3 can be first transferred into the memory, and after sorting in the memory, they are written into the SST in Level 3. And so on.

[0088] In this way, overall, the data stored in the SST of the upper layer is newer than the data stored in the SST of the lower layer. The newest data is stored in the memory, the second newest data is stored in Level 0, and the oldest data is stored in the SST in the lowest level. In addition, through compaction, garbage collection can also be performed, and data marked for deletion can be deleted.

[0089] The sorted kv can be efficiently searched, for example, through binary search for efficient search. Binary search is also called dichotomic search, and the algorithm is as follows: define left as the leftmost element position of the ordered table, right as the rightmost element position of the ordered table, and define mid=(left+right) / 2, that is, the middle position of the ordered table; compare the value to be searched with the value at the position of mid; since the list is ordered, if the value to be searched is smaller than mid, only the first half of the table needs to be searched, otherwise only the second half of the table needs to be searched (if the two values are equal after the first comparison, the current value is returned directly). In this way, until the searched value is found or it is determined that the searched value is not in the list (i.e., the search fails).

[0090] Such a storage engine has read amplification and write amplification problems when reading and writing data, which will be described in detail below.

[0091] In the process of executing a transaction by the execution module, it can be required to read some existing state. For example, for a normal transfer transaction, external account A transfers a certain amount (e.g., f) of assets to external account B, then the account balance needs to be increased or decreased. Assuming that before the transaction is executed, the balance of account A is a, and the balance of account B is b, then the execution of the transaction is to set the balance of account A to the value of (a-f), and to set the balance of account B to the value of (b+f). Therefore, the transaction needs to read the values of the two state variables a and b when it is executed. For another example, a transaction of calling a contract, external account C initiates a call to contract D, then C initiates a transaction pointing to the address of contract account D, and indicates the called function and input parameters in the data field of the transaction. Assuming that the logic of the called function in contract D includes judging the value of a global state d in the contract, and the value of d is a boolean type, the judgment logic includes executing branch 1 if it is true, and executing branch 2 if it is false. Therefore, the transaction of calling the contract needs to read the value of the state d when it is executed.

[0092] In the transaction execution process, whether the values of the state variables a and b are read or the value of the state variable d is read, the execution module can first search for the value of the state variable in the memory of the execution module. If the value does not exist, a read instruction is sent to the storage module. The read instruction can include the address of the state to be read, that is, the key value of the state. After the storage module receives the read instruction, the root node of the state tree is found in the tree module, and the state key value to be searched is matched with the shared nibble (s) field (for Extension Node) or slot (for Branch Node) of the root node from the beginning. After the matching, the hash of the next layer tree node (which can be an Internal Node or a Leaf Node, and an Internal Node is taken as an example for illustration) is read from the matching position, and then the hash is searched in the memory of the tree module. If the hash is still not found, it is searched in the memory of the state database module. If the hash is still not found, it needs to be searched in the file of the state database module. Specifically, the SST in Level 0 can be searched first, and if the hash is still not found, the SST in Level 1 can be searched, and the hash can be searched in the SST in the lower level in this way until the next Internal Node pointed by the hash value is found. After the Internal Node is resolved, the remaining part of the state address key value to be read is matched from the front. If the matching is successful, the hash value is read from the matching position, and then the next tree node pointed by the hash value is jumped to. In this way, the Internal Node is continuously resolved, and the remaining part of the state address key value to be read is matched from the front. The hash value at the matching position is used as the basis for searching the next node or leaf node. Until the Leaf node is matched, the value of the state is read from the Leaf node. In this process, the k-v of each level of tree node may not exist in the memory of the tree module, but in the state database module. Therefore, it may be necessary to read from the state database module to the memory. The key can be searched in the MemTable or Immutable MemTable of the state database module first. If the key does not exist, the SST files on the disk need to be further searched. For the Internal Node and Leaf node existing on the disk, they need to be loaded into the memory and decoded (deserialized) to obtain the content therein. Specifically, for example, the sst file in level 0 is searched one by one. If each SST in Level 0 is sorted, a binary search can be performed in each SST according to the hash value of the Internal Node / Leaf Node. After the search, the v is loaded into the memory and decoded and matched.If not found in Level 0 SST, further binary search in Level 1 SST based on the hash value of the intermediate / leaf node, and binary search in Level 2 SST if not found. If found, load the corresponding v of k into memory and decode. Repeat until the leaf node is found and the value of v is read. Since the SSTs in each level are sorted, binary search can be done in each level.

[0093] From the above process of reading a state k-v, it can be seen that the reading process needs to do binary search in multiple SSTs in different levels based on the hash value of the tree node, which may require reading a large number of files in multiple SSTs and loading them into memory, which brings the problem of read amplification. Assuming that the database includes Level 0, Level 1, Level 2,..., Level M-1, a total of M layers, then in the worst case, reading the data of a state requires at least M times of access to the disk (more than M because in the worst case, the N SSTs of Level 0 layer may need to be searched more than once and less than or equal to N times).

[0094] In addition, the tree building module can also need to do a binary search from Level 0, Level 1, Level 2, etc. if it lacks the k-v of a certain tree node in the process of building the k-v of all tree nodes on the path to the root node according to the state k-v. The principle is similar to the above process. In the above transaction example, after the transaction is executed, the value of the execution result (a-f) / the value of (b+f) / the value of the contract state d needs to be written into the state database. For the above values to be written into the database, the execution module calls the storage interface of the storage module to output the key-value value of the state to the storage module. The tree building module in the storage module generates the tree node k-v of the tree root to the intermediate node and the leaf node of the tree structure according to the state k-v, and also writes these tree node k-v to the WAL module, and then writes this series of tree node k-v to the MemTable of the state database module and marks it as dirty data. Dirty data generally refers to data that has been written into the MemTable but has not yet been written into the persistent storage (such as SSTable). The dirty data can be written to the disk in the flush process described above. The state database module further writes some k-v including the tree node k-v to the SST file on the disk. Once the MemTable is persisted to the SSTable, the data in it is no longer dirty data, i.e. becomes "clean" data. As can be seen, the above process of persisting a state k-v is relatively complex, consumes a lot of computing and memory resources, and causes the write amplification problem.

[0095] The complexity of the above read process and write process and the read amplification and write amplification problems pose challenges to the high performance requirements and large-scale applications of blockchains.

[0096] The present application provides a method embodiment for reading blockchain state data. The method embodiment can be applied to a storage module of a blockchain node. The storage module has a tree structure of the world state built in the memory. The leaf node of the tree structure can include the content of the state data or the location index of the state data in the data file of the persistent storage medium.

[0097] In one example, the tree structure as a whole can be as shown in FIG. 10, which is also similar to FIG. 5 to some extent. In particular, if there is state data in the leaf node in the memory, the location index of the state data in the data file can be used as shown in FIG. 5, for example, the leaf node A11 in FIG. 5 has state data in the memory, i.e. Zhang San_A = 20. If there is no state data in the leaf node in the memory, the location index of the state data in the data file can be used.

[0098] In this application, the actual data and the index are separated, which helps to improve the flexibility and performance of the system. The basic concepts involved here include data files and index files. Among them, the data file is a file that stores the actual content; the index file is a file that stores the index pointing to the location of the data file. The working principle is that the data content is written into the data file, and the location of the data in the file (such as the file name, offset, and length) is recorded; then, an entry is created in the index file, which contains: the key (a unique identifier for searching) points to the reference of the data file (file name, offset, etc.). In this way, during data retrieval, the data location can be quickly located through the index file, and then the actual content can be read from the data file according to the location information. The advantages of such a way are: ① flexibility, data and index can be independently managed and optimized; ② performance, index is usually small and can be loaded into memory to speed up query; ③ space efficiency: avoid storing a large amount of duplicate data in the index; ④ update efficiency: when modifying data, only the location information in the index needs to be updated.

[0099] For example, in Figure 10, the location index is represented by location. Still taking the A11 node as an example, if there is no state data in the memory, the location field included therein can be used to store the location index of the state data in the data file, which is, for example, <2, 750, 210>. This <2, 750, 210> can indicate that the state data is located in "file 2" in the data file, the starting position is the 750KB of "file 2", and the length is 210KB. As shown in the data file at the lower left corner of Figure 10, assuming that the size of each file is 1024KB, the logical address range of the index is 0KB-1023KB. In this way, the state data of A11 actually occupies the range from 750KB to 959KB in file 2.

[0100] As shown in Figure 9, this embodiment includes:

[0101] S910: The storage module of the blockchain node receives an instruction to find a state key, and finds the leaf node corresponding to the state key on the tree structure in the memory.

[0102] As shown in the foregoing Figure 6, the execution module can generate an execution result by executing a normal transfer transaction / transaction involving a contract, and send it to the storage module. Specifically, for example, the value of a state variable needs to be read during the execution of the contract. The execution module can first find whether the value of the state variable exists in the memory of the execution module, and if not, send a read instruction to the storage module. The read instruction can include the address of the state to be read, i.e., the key value of the state.

[0103] The storage module includes a tree construction module. The tree construction module constructs a tree structure of the world state in the memory. If it is a cold start of the blockchain node, i.e., there is no tree structure of the world state in the memory, each tree node of the tree structure can be loaded from the disk and organized into a tree in the memory, and this process also involves loading the leaf nodes in the tree structure. Here, an example is given for the case where there is an incomplete tree structure in the tree construction module, and the cold start loading case is similar. Since the capacity of the memory is generally limited, the LRU (Least Recently Used, a commonly used page replacement algorithm that selects the least recently used page to be discarded) algorithm is generally used to discard the tree nodes that have not been accessed for a long time from the memory. In this way, each leaf node on the tree structure constructed by the tree construction module in the memory has a certain possibility of being discarded. For the leaf nodes of the world state tree, some may be in the memory and some may not be in the memory. In addition, for the content in the tree node, such as the state data in the leaf node, a similar discard mechanism can also be used, or the memory can also not maintain the state data.

[0104] For the state key to be found, if the memory of the tree construction module has the leaf node corresponding to the state key, it can be found directly in the memory. This case can be referred to in FIG. 5, the key corresponding to the leaf node is directly found in the memory, so that the value is read from it. Further, the state data can be read from the value. If the memory of the tree construction module does not have the leaf node corresponding to the state key, or although it has the leaf node, but there is no state data to be found in it, further search is needed in the state database module. For the case of using the LSM tree for the state database, as described above, the search can be first performed in the MemTable, and if not found, the search is performed in the file in the disk.

[0105] S920: Obtain the position index contained in the leaf node corresponding to the tree node key, the position index pointing to the position in the data file in the persistent storage medium.

[0106] If the leaf node to be searched does not exist in the memory of the tree module, it needs to be searched and loaded from the state database module. As mentioned above, if the state data does not exist in the memory, the location field included in the state data can be used, and the content of the location field is, for example, <2, 750, 210> in the location field of the leaf node A11 in FIG. 10. The <2, 750, 210> is a position index, which indicates that the state data is located in the file 2 of the data file, the starting position is the 750 KB, and the length is 210 KB. As shown in the data file in the lower left corner of FIG. 10, assuming that the size of each file is 1024 MB, the logical address range of the index is 0 KB-1023 KB. In this way, the state data of A11 actually occupies the range from the 750 KB to the 959 KB in the file 2.

[0107] If the leaf node to be searched does not exist in the memory of the tree module, it needs to be searched and loaded from the state database module. As mentioned above, if the state data does not exist in the memory, the location field included in the state data can be used, and the content of the location field is, for example, <2, 750, 210> in the location field of the leaf node A11 in FIG. 10. The <2, 750, 210> is a position index, which indicates that the state data is located in the file 2 of the data file, the starting position is the 750 KB, and the length is 210 KB. As shown in the data file in the lower left corner of FIG. 10, assuming that the size of each file is 1024 MB, the logical address range of the index is 0 KB-1023 KB. In this way, the state data of A11 actually occupies the range from the 750 KB to the 959 KB in the file 2.

[0108] Table 2, k-v of the tree node actually stored in the database

[0109] In Table 2 above, similar to Table 1, H() represents the hash calculation. In this way, the hash value of the next tree node is anchored in the previous tree node. Through such layer-by-layer hashing, the root hash of the entire state trie tree is obtained, and the root hash is locked into the state root field of the block header. Assuming that the k-v pairs in the table are stored in the underlying state database module, saved on the disk, and adopt a similar LSM structure. In this way, similar to the foregoing, after the storage module receives a read instruction, the root node of the state tree node can be found in the tree construction module, and the state key value to be searched is matched with the shared nibble(s) field (for Extension Node) or slot (for Branch Node) of the root node from the beginning, and then the hash of the next layer tree node is read from the matching position, and then the hash is preferentially searched in the memory of the tree construction module. If it is not found, it is searched in the memory of the state database module, and if it is still not found, it needs to be searched in the file of the state database module. Specifically, the SST in Level 0 can be preferentially searched, and if it is still not found, it can be searched in the SST of Level 1, and so on, until the next Internal Node pointed to by the hash value is found; after the Internal Node is resolved, the remaining part of the state address key value to be read is matched from the front, and if the match is found, the hash value is read from the matching position, and then the next tree node pointed to by the hash value is jumped to. Thus, the Internal Node is continuously resolved and the remaining part of the state address key value to be read is matched from the front, and the hash value at the matching position is used as the basis for searching the next node or leaf node, until the Leaf node is matched, and thus the value of the state is read from the Leaf node. In this process, the k-v of each level of tree node may not exist in the memory of the tree construction module, but in the state database module. Therefore, it may need to be read from the state database module. The key can be first searched in the MemTable or Immutable MemTable of the state database module, and if it does not exist, it needs to be further searched in the SST file on the disk. For the Internal Node and Leaf node existing on the disk, it needs to be loaded into the memory and decoded (deserialized) to obtain the content therein. Specifically, for example, the sst file in level 0 is searched one by one, and if each SST in Level 0 is sorted, a binary search can be performed in each SST according to the hash value of the intermediate node / leaf node, and after the search is found, the v is loaded into the memory and decoded and matched.If not found in Level 0 SST, further binary search in Level 1 according to the hash value of the intermediate node / leaf node, if not found, binary search in Level 2. If found, load the corresponding v of k into memory and decode. In this way, until the leaf node of the tree structure is matched and the value of the value is read. The above search in Level 1, Level 2 and lower Level, because the overall SST in these levels is sorted, so generally one binary search can be done in this level.

[0110] In this way, the tree node k-v of the found leaf node can be loaded into memory. For example, A11, load the contents of the leaf node value prefix:2, Key-end:35b2e4, location: (2, 750, 210) into memory. <2, 750, 210> in it is the location index of the value content in the file.

[0111] S930: Load the value value of the data file position pointed by the location index in the persistent storage medium into the memory and read the state data therein.

[0112] Still taking A11 as an example, the location index <2, 750, 210> points to the position in the data file in the persistent storage medium. In this way, the value value of the data file position pointed by the location index <2, 750, 210> in the persistent storage medium can be loaded into the memory and the state data therein can be read, that is, the data from the starting position 750KB, the length of 210KB in the file 2 in the data file is loaded into the memory, so as to read the state data therein, that is, "Zhang San_A=20".

[0113] Through the location index, the position in the data file can be directly located, so that the data file therein can be directly loaded and the state data can be read therefrom.

[0114] For the case where the memory of the tree module does not have the state data although it has the leaf node to be searched, it can be directly read in the corresponding data file according to the location in the leaf node in the memory. In this way, the k-v of the leaf node is stored in the SST file of the persistent storage, and the process of multiple binary searches in the SST is avoided.

[0115] For the case that the tree module does not have the leaf node to be searched in the memory, and needs to search and load the leaf node from the state database module, in fact, a certain amount of content needs to be read from the disk to the memory and then searched. In the implementation mode corresponding to Table 1, the k-v of the tree node is stored in the disk, and the value of the leaf node includes the state data, for example, H(11) in Table 1 corresponds to the content Zhangsan_A=20, H(12) corresponds to the content Lisi_B=20, H(15) corresponds to the content storedData=s, and H(16) corresponds to the content Wangwu_A=20. Generally, the state data occupies a large space, which accounts for more than 90% of the total space of a k-v. In the implementation mode corresponding to Table 2, the index and data are separated, and the index stores the location of the data file where the state data is located instead of the state data itself, for example, H(11) in Table 2 corresponds to the content location(2, 750, 210), H(12) corresponds to the content (3, 350, 210), H(15) corresponds to the content (5, 760, 140), and H(16) corresponds to the content location:(5, 170, 210). The actual state is stored in the corresponding location in the data file, as shown in the data file and state data in FIG. 10. In the process of searching for the leaf node, only the index file can be searched, so that more index files can be loaded into the memory per unit of space for searching. The searching efficiency of the memory is obviously higher than that of the disk, and generally, the searched content is loaded into the memory before searching. The implementation mode of Table 2 can find the leaf node faster than the implementation mode of Table 1, because more indexes can be loaded into the memory per unit of memory space. In the implementation mode of Table 1, if a batch of k-v is read into the memory and the leaf node is not found, another batch of k-v needs to be read into the memory for searching again. Because the state content occupies a large space, the number of k-v per unit of memory space is relatively small, so the number of times of reading from the disk is generally more frequent, and the reading speed of the disk is much slower than that of the memory. Therefore, the searching efficiency of the implementation mode of Table 1 is low.

[0116] The above describes the specific process of the embodiment of the method of Figure 9 in combination with Figure 10. In Figure 10, the structure of the two-level MPT tree is still used, and the structure of the intermediate nodes in each level of the tree includes two types of tree nodes, Extension Node and Branch Node. In a variant, the tree node such as Branch Node can be used as the intermediate node and the root node of the tree, as shown in Figure 11. In this way, from the root node of the tree to the leaf node through the intermediate node, the order combination of the slot positions in the branch nodes passed through in the middle can constitute part of the content in the state key. The hash value of the next level node can be stored in the slot position of the previous level node. In Figure 11, the structure of the two-level tree is still used, and the leaf nodes in the upper level tree can store the account state (including the state of the external account and the contract account), and the leaf nodes in the lower level tree store the state of the contract. In the leaf nodes storing the state of the external account, the state of the contract account or the state of the contract, a position index can be used. For example, the leaf nodes of the upper level tree include the account state as the following four rows in the table: H(M1), H(M2), H(M3), and H(M4).

[0117] Table 3: Tree nodes k-v actually stored in the database

[0118] Through the position index, the position in the data file can be directly located, so that the data file therein can be directly loaded, and the state data can be read therefrom. Further, the leaf nodes of the lower level tree include the contract state as the following four rows in the table: H(Z1), H(Z2), H(Z3), and H(Z4).

[0119] The data file is shown in Figure 11, for example, and the content in the data file is as follows, for example:

[0120] M1: Nonce: n1, balance: 45.0 ETH

[0121] M2: Nonce: n2, balance: 1.00 WEI

[0122] M3: Nonce: n3, balance: 1.1 ETH

[0123] M4: Nonce: n1, balance: 0.12 ETH, codehash: c1, storage: s1

[0124] Z1: Zhang San_A = 20

[0125] Z2: Li Si_B = 50

[0126] Z3: Wang Wu_A = 35

[0127] Z4: storedData = s

[0128] No matter the upper level tree or the lower level tree, the location in the leaf node can quickly locate the position in the data file. In this way, the k-v of the leaf node stored in the SST file of the persistent storage is avoided, and the process of multiple binary search in the SST according to the key (hash value of the content) of the leaf node is avoided. In the example of FIG. 11, the blockchain state data is read in the manner of FIG. 9, and the position in the data file can be directly located according to the location index, so the content located in the corresponding position in the data file can be directly loaded into the memory, thereby avoiding the read amplification problem caused by reading a large number of files in the SST of multiple levels and loading them into the memory. As the leaf node A4 of the upper level tree, it can be stored in the manner shown in FIG. 10, or in the manner shown in FIG. 11.

[0129] The external account, the contract account, and the contract state can each have a key in the form of a fixed-length string. For example, the key of the external account and the contract account can be an account address, and the key of the contract state can be a string of the same length. For another example, the key of the external account and the contract account can be a hash value of an account address obtained by using a hash algorithm, such as a sha3 algorithm, and the key of the contract state can be sha3(contract name + position of state variable declaration). The external account, the contract account, and the contract state are collectively referred to as state keys, which have the same length and format. For example, the length of the state key is 4 bytes, i.e., 32 bits. In this way, assuming that each of the root node (B0), the intermediate nodes (..., C5,..., C13,..., C5D1,..., C5D9,..., C5D14,..., C13D2,..., C13D10,...), is a 16-ary tree, on the one hand, each slot of the intermediate node (e.g., 0, 1, 2,..., d, e, f, which are 16 slots in B0) can be filled with a hash value of a next tree node, and on the other hand, the position of the slot of the root / intermediate node can represent 4 bits of the key. 4 bits constitute a nibble, so that 8 layers of the root node and the intermediate node can be loaded into 32 bits, i.e., 8 bytes, which is the total state key. The 32 bits of the state key can be stored in a nibble from the top intermediate node to the bottom intermediate node and to the leaf node, from top to bottom. In this way, for the case of fixed expansion of the intermediate node, the last 4 bits of the key can be stored in the leaf node. In the case of fixed expansion of the intermediate node, from C* to C13D* in FIG. 11, to M* at the bottom layer, there are 8 layers in total. In another case, a prefix, an infix, and / or a suffix can be used, so that the intermediate node and the leaf node above it can be less than 8 layers.

[0130] In addition, the account state and the contract state can also be stored in a one-layer tree structure, as shown in FIG. 12. Since the key of the contract state is a hash value, based on the discrete characteristics of the hash algorithm, the state keys of different contract states can be paths from the root node to different leaf nodes in the one-layer tree structure. In this way, the values of different states of the same contract can exist in different leaf nodes at the bottom layer of the one-layer tree structure, and will not be gathered under the contract account to which they belong. In fact, in the one-layer tree structure, the account state and the contract state are dispersed in the leaf nodes at the bottom layer.

[0131] In addition, on the basis of Fig. 12, prefix and / or infix can be compressed, as shown in Fig. 13. In the case of infix compression, for example, the tree node key of Ml is 0x52d1479e (0x means each bit is represented by a hexadecimal number), and the tree node key of Zl is 0x52d9ab36, then Ml and Zl have a common infix 2d, so in the tree node C5, in addition to the 16-way tree separated 1 and 9, C5 can also have the compressed infix 2d, as shown in the shared nibbles field in Fig. 13. In the case of suffix compression, for example, represented by key-end, then the key-end in the tree node Ml is, for example, 479e, and the key-end in the tree node Zl is, for example, 36. With prefix and / or infix compression, the number of layers of the tree can be reduced.

[0132] Regardless of whether compression is performed, for a lookup state key, the path of the state key can be matched from the root node of the tree structure, segment by segment, until the leaf node of the tree structure corresponding to the lookup state key is found. In one approach, the storage of the root node and the intermediate nodes is in the form of key-value, where the key is the hash value of the value, similar to the structure in Table 3. In this way, the hash of the path of the state key can be matched from the previous layer of tree nodes in order, and the next layer of tree nodes can be found according to the hash, until the leaf node of the tree structure corresponding to the state key is found.

[0133] In addition, the key of the tree node k-v actually stored in the database can also not be the hash value of the value, but a part of the value on the path of the state key, for example, the value of the part of the key from the root node to the current tree node (without compression of the prefix / infix, as shown in Table 4, in combination with Fig. 12), or the value of the part of the key after the previous tree node (with compression of the prefix / infix, as shown in Table 5, in combination with Fig. 13).

[0134] Table 4, tree node k-v actually stored in the database

[0135] According to Table 4, for example, the state key for lookup is 0x59...36 (leaf node Z1), starting from the root node of the tree structure, the left 1st bit 5 of the state key can be matched to the tree node with key 0x5 in the database (h(C5) in the value of the tree node with key 0x5 can be used to verify the hash value on slot 5 in the root node, and if the same, it means that the tree node with key 0x5 is the child node of slot 5 in the tree node with key 0x); further, the left 2nd bit 9 of the state key can be matched to the tree node with key 0x9 in the database (h(C5D9) in the value of the tree node with key 0x9 can be used to verify the hash value on slot 9 in the parent node, and if the same, it means that the tree node with key 0x9 is the child node of the tree node with key 0x5); and so on. Finally, the last bit 6 of the state key can be matched to the tree node with key 0x6 in the database (h(Z1) in the value of the tree node with key 0x6 can be used to verify the hash value on slot 6 in the parent node, and if the same, it means that the tree node with key 0x6 is the child node of the parent node).

[0136] Table 5, tree nodes k-v actually stored in the database

[0137] According to Table 5, for example, the state key for lookup is 0x52d9...36 (leaf node Z1), starting from the root node of the tree structure, the left 1st bit 5 of the state key can be matched to the tree node with key 0x5 in the database, if no same key is matched, or the hash value in the value of the tree node with key is inconsistent with h(C5) in the root node, then the left 1st-2nd bit 52 of the state key is matched to the database, and so on, until a match is made. When the left 1st-3rd bit 52d of the state key is matched to the tree node with key 0x52d in the database, and H(C5) in the value of the tree node is the same as the hash value on slot 5 in the root node, it means that a match is made. Further, the left 1st-4th bit 52d9 of the state key can be matched to the database, if no same key is matched, or the hash value in the value of the tree node with key is inconsistent with h(C5) in the root node, then the left 1st-2nd bit 52 of the state key is matched to the database, and if a match is made, and H(C5D9) in the value of the matched tree node is the same as the hash value on slot 9 in the parent node, it means that a match is made. Further, the left 1st-5th bit of the state key is matched to the database, the left 1st-6th bit of the state key is matched to the database, and so on, until the leaf node is matched.

[0138] In another implementation, the full state key or the corresponding full state key can be stored in the leaf node. For example, as shown in FIG. 14, the key-full field of the leaf node can store the full key of the corresponding state. The key-value of the leaf node stored in the database has the key as the full key of the state corresponding to the leaf node. In this way, when searching for a state key, the key of the leaf node in the database can be directly matched according to the key, without the need to match the key of the intermediate node. Obviously, such a search method is extremely efficient for query operations. In fact, in the above FIGS. 10-13, the full state key can also be used as the key of the leaf node.

[0139] In the above embodiments of FIGS. 9-14, the location index stored in the leaf node can be used to quickly locate the position of the value of the leaf node in the data file after the leaf node is found. In this way, the content of the corresponding position in the data file can be directly loaded into the memory, which also avoids the read amplification problem caused by reading and loading a large number of files in the memory in multiple levels of SST. This also avoids the process of storing the k-v of the leaf node in the SST file of the persistent storage and performing multiple binary search operations in the SST according to the key (hash value of the value content) of the leaf node. Moreover, similarly, for the memory of the tree construction module that does not have the leaf node to be searched, the above embodiments can only search the index file, so that more index files can be loaded into the memory in a unit of space for searching, and the leaf node can be found faster.

[0140] As described above, the state root in the block header stores the hash value of the tree root of the anchored lower MPT tree. This hash value is actually obtained by calculating the hash from the leaf node to the upper layer according to the rules, as described above. Generally, the storage module of the blockchain node constructs the world state of the tree structure in the memory through the tree construction module. Specifically, in addition to the leaf node in the above FIGS. 12-14, the intermediate node and the root node are also included, as described above in the above tables 2-5.

[0141] Moreover, the chain data structure of the blockchain is realized by anchoring the hash of the next block to the Prev Hash of the previous block, as shown in FIGS. 3 and 4, and the blocks with different block numbers exist on the blockchain. These block numbers are also called versions. The corresponding tree structure may change under different versions of blocks.

[0142] Those skilled in the art know that the essence of a blockchain is a chain structure composed of a series of data blocks (blocks) associated by hashing. Each block has a corresponding world state of the block, but each block does not necessarily contain a complete world state, but in most cases contains a reference to the previous world state. The following explains this:

[0143] In the block structure of Ethereum, when the value of a key-value pair changes, the content of the leaf node of the corresponding MPT tree changes. Correspondingly, the relevant hash values stored in a series of intermediate nodes and the root node above the leaf node will also change. In the structure shown in Table 1, the changed leaf nodes and intermediate nodes, root nodes will also be added at the end of Table 1. At the same time, the values of many state variables in the contract storage may not change.

[0144] As shown in the Ethereum block structure diagram of Figure 15, the difference between Figure 15 and Figure 3 is that the root node of the two-level Merkle tree under the State Root in block N+1 refers to the state variables in block N that do not change. For example, in the contract storage of a contract, the value of the same state variable changes from 29 in block N to 45 in block N+1, assuming that other state variables do not change, then in block N+1, in addition to the leaf node storing the value changed to 45 and the intermediate nodes related to it, the other leaf nodes and intermediate nodes that do not change directly refer to the same leaf node and intermediate node in block N. Here, N and N+1 are two adjacent blocks. It can be understood that for the block structure of a plurality of consecutive blocks on the blockchain, the leaf nodes and intermediate nodes that do not change in block N+1 relative to the previous block all refer to the same leaf node and intermediate node that was last updated to this value. The same leaf node and intermediate node that was last updated to this value, for example, is the same leaf node and related intermediate node that was last updated to this value in block N-1, the same leaf node and related intermediate node that was last updated to this value in block 5, and so on. The different blocks here can also be referred to as different versions, and the block number can be the version number. Here, the reference is achieved by recording the hash value of the lower layer node through the upper layer node. The advantage is obvious, that is, the leaf nodes and intermediate nodes that do not change are not stored repeatedly in the underlying database.

[0145] Here still take the same contract storage in N+1 version as an example, for example, the content of a certain tree node has changed, and its hash will also change accordingly. The MPT takes the hash as the index in the database, so that for each value, there is a definite record in the database. The MPT is associated with the parent and child nodes according to the node hash, so when the content of a node changes, the only thing that changes for the parent node is a hash index value; the content of the parent node also changes, resulting in a new parent node at a higher level, recursively passing on the impact to the root node. Ultimately, a change corresponds to the creation of a new path from the changed node to the root node, and the old node can still be accessed according to the old root node through the old path.

[0146] As shown in FIG. 15, when the content of a node in the MPT changes from 29 in N version to 45 in N+1 version, assuming that other states in the contract state do not change in the two versions before and after, the changed 45 in the world state of N+1 version corresponds to the creation of a new path to the contract root node (Storage root). And the other leaf nodes and intermediate nodes that do not change reuse the leaf nodes and / or intermediate nodes in the previous version (i.e., the version of block number N) through the hash pointer, thereby constructing a new MPT tree for the contract storage in N+1 version, while still retaining its old path. As shown in FIG. 18, in the same contract storage, the leaf nodes / intermediate nodes whose values do not change in N+1 version relative to N version include V, U, T, S, etc., so in the storage of the contract in N+1 version, in addition to creating a new path from 45 to Storage root, the Storage root in N+1 version is indexed to V, U, T, S in N version through hash, but does not include the leaf node with value 29 and the related intermediate nodes. Assuming that the contract is deployed in N version, the CodeHash is similar, and the contract code corresponding to the CodeHash exists in the state database (StateDB) corresponding to N version, and the CodeHash in N+1 version also points to the contract code in N version.

[0147] In addition to the contract storage, similarly, other account storages (including external account and contract account storages) can also be in a similar manner, as shown in FIG. 15, for the account storage that does not change in N+1 version relative to N version, the State Root in the N+1 block header points to the storage of external accounts or contract accounts L, M, N, P, Q, R, etc. in N version, and only the changed leaf nodes and related intermediate nodes are stored in the account storage corresponding to N+1 version, which is not described in detail.

[0148] All the states under the current block, in fact, many of them are likely to be updated in the previous block and continue to the current block without change. Similar to Ethereum, this is also called the current state, stored in the currentDB. The currentDB is used to store the latest "current state" data, such as the latest account state, contract code, and contract storage. Moreover, as the block grows, the data in the currentDB can be constantly modified.

[0149] As described in the foregoing FIG. 3 and the contents of FIG. 15 above, it is highly redundant to build a global MPT tree of all states for each block, and to reference the same leaf node and intermediate node in the previous block that was last updated to this value is an efficient data storage method. Moreover, the changed state in each block is likely to be part of the global state. This is also similar to Ethereum, also known as the history state, stored in the historyDB. The historyDB is used to store historical state data, thereby providing a complete historical view of the entire chain.

[0150] The present application provides a method for constructing a tree structure-based world state, comprising:

[0151] S170: Receive state key-value.

[0152] S172: According to the construction rule of the tree structure, generate the leaf node of the tree structure corresponding to the state key-value pair; calculate the hash value of the leaf node according to the content in the leaf node, and generate or update the upper tree node according to the hash value of the leaf node and the state key, until the root node of the tree.

[0153] Among them, the leaf node can be in the form of the foregoing data file, or in the form of the foregoing KVDB. For the form of the foregoing data file, the leaf node can be to generate a position index of the state value in the data file in the persistent storage medium and a hash value of the state value content.

[0154] S174: According to the logical page structure of the division, generate the corresponding memory page of the generated / updated tree node, and the memory page is used to represent the content of all corresponding tree nodes in the logical page.

[0155] In the present application, the entire Merkle tree structure can be divided into multiple LogicalPages (logical pages), which can be aggregated according to the node association relationship of the tree structure to form a LogicalPage by aggregating several adjacent tree nodes above and below, such as aggregating 16 child nodes of the 2-level dictionary tree to form a LogicalPage. Among them, there are multiple layers of LogicalPages from the root node to the leaf node of the Merkle tree, and the LogicalPages have parent-child and sibling relationships, thereby forming a complete Merkle tree. In this way, the tree structure can be divided into multiple logical pages, each of which contains at least one tree node, and each logical page contains different tree nodes, and the logical page maintains the content of the corresponding tree node of the current latest version.

[0156] As shown in FIG. 16, inside each LogicalPage, a MemoryPage (memory page) can be maintained to represent the content of all tree nodes in the corresponding logical page of the current latest version of the logical page. Further, the content of the tree node maintained by the logical page can be generated into a BasePage (base page) and a DeltaPage (incremental page) according to continuous version updates and generation / modification behaviors. Specifically, a BasePage and a DeltaPage are generated according to generation / modification behaviors, for example, for continuous state changes, such as including state variables a=5, b=8, and c=3 in version N, a=5, b=8, and c=3 can be used as the content in the BasePage. For a=6 in version N+1, a=8 in version N+2, and assuming that b and c do not change, a=6 in version N+1 and a=8 in version N+2 can be used as the DeltaPage based on the BasePage, such as DeltaPage1, and b and c are not included in DeltaPage1. For a=11 in version N+3 and a=15 in version N+4, a=11 in version N+3 and a=15 in version N+4 can be used as the DeltaPage based on the BasePage, such as DeltaPage2, and assuming that b and c do not change, b and c are not included in DeltaPage2. Similarly, BasePage and DeltaPage can be used as the smallest unit of the memory structure of the tree. In addition, BasePage can be used as the smallest unit of disk persistence of the tree. On this basis, DeltaPage can also be used as the smallest unit of disk persistence of the tree.

[0157] It is noted that the BasePage here is a checkpoint of the whole LogicalPage content, which can contain the full content of the LogicalPage at that time, such as all contained tree node information. Checkpoint is generally a snapshot of a certain state saved in a computer system, so as to continue execution from the saved state when the system fails or fails. In many cases, checkpoint is used for long-running computing tasks, safety-critical systems, distributed systems, and database systems, etc.

[0158] [According to Rule 91 correction 18.12.2024] For BasePage, the state modification can be generated once BasePage for every predetermined number of times (such as m times), as shown by basepage2 on the right side of the lower right gray box in Figure 17. As in the previous example, the state variable a = 5 in version N, which can be used as the content in the base page BasePage1, a = 6 in version N+1, a = 8 in version N+2, a = 6 in version N+1 and a = 8 in version N+2 can be used as the DeltaPage1 based on this BasePage. For a = 11 in version N+3 and a = 15 in version N+4, a = 11 in version N+3 and a = 15 in version N+4 can be used as the DeltaPage2 based on this BasePage, and for a = 20 in version N+5, assuming that the modification reaches the predetermined number of 5, the values a = 20, b = 8 and c = 3 in version N+5 can be used as the content in this BasePage2.

[0159] Similarly, DeltaPage describes several version modifications of LogicalPage, and aggregates multiple modifications into a set, such as generating a DeltaPage every M modifications, and creating a new DeltaPage to collect subsequent version modification operations. As in the previous example, for a = 6 in version N+1 and a = 8 in version N+2, a = 6 in version N+1 and a = 8 in version N+2 can be used as the DeltaPage1 based on this BasePage, for a = 11 in version N+3 and a = 15 in version N+4, a = 11 in version N+3 and a = 15 in version N+4 can be used as the DeltaPage2 based on this BasePage, it can be seen that each DeltaPage sets up 2 version modification operations to create an incremental page.

[0160] For each modification of the BasePage and the DeltaPage, corresponding dirty data is generated in the memory. The BasePage and the DeltaPage can be batched for disk persistence when the memory occupied by the BasePage and the DeltaPage reaches a predetermined amount, so as to avoid persisting all dirty data each time the modification is made, and continuously occupying the memory and CPU resources. The memory generation and disk persistence of the BasePage and the DeltaPage can be performed in the background.

[0161] When the storage module persists the world state of the tree structure constructed in the memory through the structure of the logical page, the state data can be cached according to a predetermined strategy, such as an LRU strategy, according to the hot and cold characteristics of the state data and the logical page as a granularity. In this way, if the MemoryPage is discarded, the corresponding BasePage and DeltaPage are read, and the MemoryPage is replayed.

[0162] The above scheme provided in the present application describes a scheme of cutting the world state of a tree structure according to a Page, divides the tree structure into a LogicalPage, manages the MemoryPage / BasePage / DeltaPage in the LogicalPage, optimizes each state tree modification into multiple version modifications according to the LogicalPage as a granularity, and reduces the overall write amplification. For the current version, the MemoryPage can be directly obtained according to the memory page, and for the historical version, the BasePage and the associated DeltaPage can be read to replay and obtain. The entire MemoryPage is cached in the memory, and does not affect the contract execution performance.

[0163] In the above scheme, the MemoryPage / BasePage / DeltaPage is managed in the LogicalPage, and as described above, a plurality of adjacent tree nodes can be aggregated into a LogicalPage according to the node association relationship of the tree structure, such as 16 children nodes of 2 levels of a trie, which are aggregated into a LogicalPage. Among them, there are multiple layers of LogicalPages from the root node to the leaf node of the Merkle tree, and the LogicalPages have parent-child and sibling relationships, thereby forming a complete Merkle tree. In this way, the tree structure can be divided into a plurality of logical pages, each of which contains at least one tree node, and different logical pages contain different tree nodes, and the logical page maintains the content of the corresponding tree node of the current latest version.

[0164] So, when constructing the world state based on the tree structure, in addition to generating the leaf node of the tree according to the state key-value, it will also cause changes from the generated leaf node to the intermediate node to the root node, as described in the hash value in the aforementioned S172. Moreover, the key of the state also needs to be designed, especially for the LogicalPage and the corresponding MemoryPage / BasePage / DeltaPage.

[0165] Therefore, the present application also proposes the following method for constructing the world state based on the tree structure, comprising:

[0166] S180: receiving the state key-value.

[0167] S182: generating the leaf node of the tree structure corresponding to the state key-value according to the construction rule of the tree structure; calculating the hash value of the leaf node according to the content in the leaf node, and generating or updating the upper tree node according to the hash value of the leaf node and the state key, until the root node of the tree.

[0168] Among them, the leaf node can be in the form of the aforementioned data file, or in the form of the aforementioned KVDB. For the form of the aforementioned data file, the leaf node can be to generate the position index of the state value in the data file in the persistent storage medium and the hash value of the state value content.

[0169] The process of S182 can be referred to the foregoing content, which is briefly described as follows:

[0170] As in Ethereum, when a storage module receives a write state key-value pair (k-v) request, it first hashes the key (k) (e.g., Keccak-256). In addition, the state key in S182 can also be the state key received in S180, i.e., it can not be hashed. Next, the key is used to search in the MPT. The search starts from the root of the MPT and follows the path in the tree according to the lexicographic order of the key. In this process, the key is compared with the stored path in the nodes bit by bit (or nibble by nibble, where a nibble is a hexadecimal number of one bit). During the traversal and matching, three types of nodes can be encountered: branch nodes (if the path forks at some point), extension nodes (if there is a shared prefix), and leaf nodes (which store the final value). Branch nodes are used to fork in the tree, extension nodes are used to optimize storage (by path compression), and leaf nodes store the actual values. If the complete lexicographic path of the matching key is found to exist during the search, a leaf node is reached. At this point, the value (v) stored in this leaf node can be updated. If the search and matching process finds that only part of the path is matched, new nodes (which can be branch nodes, extension nodes, or leaf nodes) can be created to complete the remaining path and eventually reach a leaf node, and the value in the leaf node can be stored or updated.

[0171] Once the leaf node is updated or created, a backtracking process is also started. This process starts from the modified leaf node and recalculates the hash value of this node. Then, it moves up to the parent node, updates the relevant reference in the parent node (which can be the direct content of the child node or the hash value of the child node content, depending on the size of the child node), and recalculates the hash value of the parent node. This process continues until the root of the MPT is reached.

[0172] Finally, when the backtracking process reaches the root node, the root hash value of the entire MPT is updated. This new root hash value represents the new state of the entire state tree, which will be included in the block header of the next block as the new state root. In this way, each block not only contains transaction information but also saves the hash value of the global state after executing these transactions through the state root.

[0173] S184: updating the version of the generated / updated tree node in the corresponding memory page according to the divided logical page structure, the memory page being used to represent the content of all tree nodes in the corresponding logical page, the logical page containing a page identifier, the page identifier including the lexicographic content and version of an upper tree node in the logical page.

[0174] It should be noted that the process of S184 can occur after S182 or during the process of S182.

[0175] Figure 18 is a complete diagram of another embodiment of the present application. Figure 18 is generally similar to Figure 13, the main difference being that, for example, the intermediate node with reference C5 and the intermediate nodes thereunder with references C5D1, C5D9, C5D14 together constitute a LogicalPage, and in the leaf nodes M1, M2, M3, M4, the key-end is stored instead of the key-full, and in the leaf nodes, in addition to the position index contained, the hash value of the corresponding state value content is also contained. Of course, in this embodiment, as mentioned above, the leaf nodes M1, M2, M3, M4 can also be key-full.

[0176] The leaf nodes can also include a hash value (valuehash) of the state value content and a key-end field, wherein the hash value of the leaf node is calculated according to the content in the leaf node, including calculation according to the hash value of the state value content in the leaf node and the key-end field, but excluding the position index of the state value in the data file in the persistent storage medium.

[0177] The leaf nodes can also include a hash value (valuehash) of the state value content and a key-end field, wherein the hash value of the leaf node is calculated according to the content in the leaf node, including calculation according to the hash value of the state value content in the leaf node and the key-end field, but excluding the position index of the state value in the data file in the persistent storage medium.

[0178] In the foregoing S182, the tree node is generated / updated. The updated tree node is integrated into the corresponding memory page according to the logical page structure described above, representing the world state tree structure under the current block number. In the present application, a version number can be set for the logical page. The version number can typically be the block number. In addition to the block number, the version number can also be data such as block hash, timestamp, state root, transaction root, receipt root, consensus round number, etc. which can uniquely identify a block. For simplicity, the block number is described below.

[0179] The version number of the logical page can be included in the page identifier of the logical page. In addition to the version number, the page identifier of the logical page can also include the lexicographic content of the contained tree nodes. Specifically, the page identifier can include the lexicographic content of the upper tree nodes in the logical page. As shown in FIG. 18, the upper tree node of the intermediate nodes with labels C5, C5D1, C5D9, and C5D14 together constitute a LogicalPage, and the upper tree node has a NodeID, such as 0xd2345 (0x represents hexadecimal), and the intermediate nodes C5D1, C5D9, and C5D14 each also have a NodeID. The PageID of the LogicalPage can be set to the NodeID of the upper tree node. These page IDs are the lexicographic content from the root node to the upper tree node in the LogicalPage (i.e., the memory page), i.e., the key distributed from the root node through the intermediate node to the lexicographic content of the upper tree node in the LogicalPage. Similarly, the NodeID is the lexicographic content from the root node to the tree node, i.e., the key distributed from the root node through the intermediate node to the lexicographic content of the tree node.

[0180] As described above, in the process of generating / updating the tree nodes of the current version, the changed tree nodes constitute dirty data. As described above, the base page and the incremental page can be generated based on the changes of the logical pages of consecutive versions. On this basis, the base page can be taken as the minimum unit of disk persistence of the tree, or the incremental page can be taken as the minimum unit of disk persistence of the tree. The base page can be generated once for every predetermined number of state modifications, or the incremental page can be generated once for every predetermined number of state modifications. When the base page and the incremental page occupy a certain amount of memory, the base page and the incremental page are batched for disk persistence.

[0181] The base page and the incremental page are persistent objects of the memory page corresponding to the logical page, and the memory page is the memory object of the logical page. The base page generally corresponds to the memory page and contains global state variables, and can have the same page ID as the corresponding memory page, and the memory page has the same page ID as the corresponding logical page. The incremental page can also correspond to the memory page and contain the tree nodes in one or more consecutive version memory pages that have changed relative to the previous adjacent base page / incremental page / version, i.e., contain the changed state variables, which are generally not global state variables, and the structure of the tree nodes in the incremental page generally does not change, so the page ID of the corresponding memory page can be the same as the NodeID of the upper tree node.

[0182] In addition, the base page and the delta page can have a version. After the operation of S184, the base page and the delta page corresponding to the version of the change of the memory page based on the continuous version can be generated. Specifically, the base page generally corresponds to one memory page and contains all the tree nodes in the corresponding memory page, that is, contains the global state variable, so it can have the same version as the corresponding memory page. The delta page can correspond to one or more memory pages and contain the tree nodes in one or more continuous versions of the memory page that have changed relative to the previous adjacent base page / delta page, that is, contain the changed state variable, but generally not the global state variable, so the version of a delta page can be the lowest or highest version of the one or more memory pages corresponding to it.

[0183] For example, a base page with a version of 4 contains state variables a=1, b=2, c=3 and corresponding intermediate nodes and root nodes. The subsequent delta page can include a=2 with a version of 5 and corresponding intermediate nodes and root nodes, a=1 with a version of 6 and corresponding intermediate nodes and root nodes, and b=4 with a version of 7 and corresponding intermediate nodes and root nodes. Among them, a=1 with a version of 6, although the same as the state variable a=1 in the base page, is different from the previous adjacent version a=2 with a version of 5, so a=1 with a version of 6 and corresponding intermediate nodes and root nodes are also included in the delta page. In addition, for the subsequent delta page, for example, the delta page containing tree nodes with versions of 7, 8 and 9, the actual tree nodes are sequentially relative to the previous adjacent delta page and version. The tree nodes with versions of 5, 6 and 7 correspond to memory pages with versions of 5, 6 and 7 respectively. This delta page containing tree nodes with versions of 5, 6 and 7 can have a version of 5 or 7, that is, the lowest or highest version of the corresponding multiple memory pages.

[0184] Moreover, a page type can also be set in the base page and the delta page to distinguish the base page and the delta page.

[0185] The above scheme is a multi-version Page splitting scheme of a Merkle state data dictionary tree, which switches the tree to a LogicalPage. Both the tree and the LogicalPage maintain a version (such as a block number). The internal management of MemoryPage / BasePage / DeltaPage is maintained according to the version. The BasePage / DeltaPage maintains the memory structure and file persistence according to the version. Through page aggregation, the overall write amplification is reduced. By using the ordered characteristics of the version, the compaction after the page is landed is avoided. The write amplification of the page landing can be reduced. By replaying based on the version, the state data reading and SPV function of any historical version are supported. In addition, in combination with the contents of the foregoing FIGS. 9-14, the state value can be stored in a data file of a persistent storage medium. The leaf node includes a position index of the state value in the data file of the persistent storage medium, so that the problem of write amplification can be further reduced.

[0186] Corresponding to the world state constructed in the above manner, the application also provides a reading method, comprising:

[0187] S190: receiving a read state key and version.

[0188] S192: according to the state key and version, matching the version and page ID in the page identifier of the memory page in the dictionary order. If the memory page includes at least two layers of tree nodes, then continue to match the version and page ID of the tree nodes below the uppermost tree node in the dictionary order until the leaf node is found.

[0189] For the received state key and version, the version and page ID in the page identifier of the memory page can be matched in the dictionary order. For example, for the intermediate node with the label C5 in FIG. 18 and the intermediate nodes below it with the labels C5D1, C5D9, and C5D14, which together constitute a LogicalPage, the corresponding memory page can be found first according to the version and page ID, and then the received state key is used to further match the tree nodes below in the memory page.

[0190] For example, for the received state key is 0xd2345167890ab and the version is 20, the version + page ID of a memory page is 20 + 0xd2345, the intermediate node marked C5 in FIG. 18 and the intermediate nodes marked C5D1, C5D9, C5D14 thereunder jointly constitute a memory page constituted by a LogicalPage which can match (0xd2345, the first 5 bits of 0xd2345167890ab). Further, in the lower layer tree nodes in the memory page, it is assumed that the C5D1 tree node is matched, i.e., the NodeID in the C5D1 tree node is matched as 0xd23451; further, the lower layer memory page of the memory page can be continuously matched. As shown in FIG. 19, the lower layer memory page is continuously matched, and according to 0xd2345167890ab, the memory page with the same version and PageID of 0xd234516 is matched, and the memory page includes the upper and lower layer tree nodes E5 and E5F2, E5F7, E5F8. Further, in the lower layer tree nodes in the memory page, it is assumed that the E5F7 tree node is matched, i.e., the NodeID in the E5F7 tree node is matched as 0xd2345167. In this way, the version and the PageID in the page identifier of the memory page are matched in the dictionary order until the last memory page and the leaf node therein are matched, and the search is completed.

[0191] As described above, the memory page is the memory object of the logical page. However, based on the cache eviction policy in the memory, there can be no currently matched memory page. Meanwhile, as described above, based on the change of the logical page with the continuous version, the base page and the incremental page can be generated, and the base page and the incremental page are the persistent objects of the memory page corresponding to the logical page. Therefore, for the case that the memory page does not exist in the memory, the corresponding base page and the incremental page can be loaded from the persistent storage medium to the memory according to the page identifier, and the memory page can be obtained by playing back the loaded base page and the incremental page.

[0192] Specifically, for example, if the memory page with the same version and matching the remaining dictionary order content is not found in the memory, the corresponding base page and the incremental page matching the remaining dictionary order content can be found in the persistent storage medium according to the page identifier. As described above, since the base page and the incremental page also have a version, and the base page generally has the same version as the corresponding memory page, and the version of an incremental page can be the lowest version in one or more memory pages corresponding thereto, there are the following two cases:

[0193] 1. For the case that the base page with the same version is found in the persistent storage medium, the corresponding base page can be loaded from the persistent storage medium to the memory according to the page identifier, and then the loaded base page is restored to the memory page.

[0194] 2. If no base page with the same version is found in the persistent storage medium, loading the corresponding base page and delta page into the memory according to the page identifier; and replaying the loaded base page and delta page to obtain the memory page.

[0195] The page identifier of the base page and the delta page can further include a page type.

[0196] Thus, the loading of the corresponding base page into the memory according to the page identifier can be loading of a base page with a version no greater than the read version, a same page ID and a base page type from the persistent storage medium. For the case 1, i.e. the case where a base page with the same version is found in the persistent storage medium, the base page with the same version, the same page ID and the base page type can be loaded into the memory. For example, if the version to be found is 20, and there is no memory page with the version 20 in the memory, and a base page with the same version 20 is found in the persistent storage medium, the base page with the same version 20, the same page ID and the base page type can be loaded into the memory. For the case 2, i.e. the case where no base page with the same version is found in the persistent storage medium, a base page with a version no greater than the read version, a same page ID and a base page type can be loaded into the memory from the persistent storage medium. For example, if the version to be found is 20, and there is no memory page with the version 20 in the memory, and no base page with the same version 20 is found in the persistent storage medium, actually, there is a BasePage1 with the version 17, a DeltaPage1 with the version 18, a DeltaPage2 with the version 20 and a BasePage2 with the version 22 in the persistent storage medium, the DeltaPage1 with the version 18 can include a tree node with the version 18 and a tree node with the version 19, and the DeltaPage2 with the version 20 can include a tree node with the version 20 and a tree node with the version 21, and thus the BasePage1 with the version no greater than 20, the same page ID and the base page type can be loaded into the memory, i.e. the version of the base page meeting the condition is 17.

[0197] For the case 1, i.e. the case where a base page with the same version is found in the persistent storage medium, the base page with the same version, the same page ID and the base page type can be loaded into the memory, and then the memory page with the same version can be recovered. For example, if the version to be found is 20, and there is no memory page with the version 20 in the memory, and a base page with the same version 20 is found in the persistent storage medium, the base page with the same version 20, the same page ID and the base page type can be loaded into the memory, and then the loaded base page with the version 20 is recovered as the memory page with the same version 20.

[0198] For the case 2 above, i.e. the case that no base page with the same version is found in the persistent storage medium, the base page with the maximum version no greater than the read version, the same page ID and the base page type can be loaded from the persistent storage medium to the memory, and then the loaded base page and the delta page can be played back to obtain the memory page. The loaded base page and the delta page can be played back to obtain the memory page, specifically, the base page with the maximum version no greater than the read version, the same page ID and the base page type can be loaded from the persistent storage medium to the memory, and the delta page with the minimum version no less than the read version, the same page ID and the delta page type can be loaded from the persistent storage medium to the memory after the version of the base page. For example, the version to be found is 20, and there is no memory page with the version 20 in the memory, and of course no base page with the same version 20 is found in the persistent storage medium. In fact, there is BasePage1 with the version 17, DeltaPage1 with the version 18, DeltaPage2 with the version 20 and BasePage2 with the version 22 in the persistent storage medium, the DeltaPage1 with the version 18 can include the tree node with the version 18 and the tree node with the version 19, and the DeltaPage2 with the version 20 can include the tree node with the version 20 and the tree node with the version 21. The BasePage1 with the maximum version 17, the version no greater than 20, the same page ID and the base page type can be loaded to the memory, i.e. the version of this base page meeting the condition is 17, and the DeltaPage1 with the version 18 and the DeltaPage2 with the version 20, the minimum version no less than the read version 20, the same page ID and the delta page type can be loaded to the memory after the version 17 of the BasePage1, and then the loaded base page and the delta page can be played back to obtain the memory page.

[0199] For the case 2, in detail, the loaded base page and the loaded incremental pages can be played back in order of page type and version to obtain the memory page. Still according to the above example, the loaded base page is BasePage1 with version 17, and the loaded incremental pages include DeltaPage1 with version 18 and DeltaPage2 with version 20. The incremental pages can be played back in order of version, i.e., on the basis of BasePage1 with version 17, the incremental pages are played back in the order of DeltaPage1 with version 18→ DeltaPage2 with version 20, to obtain the memory page. Since DeltaPage2 with version 20 includes tree nodes with version 20 and tree nodes with version 21, when playing back the pages in order to the incremental page with the maximum version no more than the read version, i.e., playing back to DeltaPage1 with version 18 which is loaded, when playing back in order to the loaded incremental page with the maximum version 20, all the tree nodes in DeltaPage2 are not played back, but the tree nodes in the loaded incremental page with the maximum version are played back in order until the same as the read version, i.e., playing back the tree nodes with version 20 in DeltaPage2, so as to obtain the memory page.

[0200] In another example, it is assumed that an incremental page includes a version of tree nodes, i.e., the version of the incremental page is the same as the version of the tree nodes contained therein. The incremental page can be played back in order of version based on the base page to the incremental page with the same version as the read version, to obtain the memory page.

[0201] The reason why the incremental page is played back from the base page to obtain the memory page is that the blockchain has the feature of de-trust, and not only data but also verifiable data needs to be provided. In detail, based on the leaf nodes and all related intermediate nodes of the global state in the base page, the incremental page is played back in order, i.e., the leaf nodes, intermediate nodes and root nodes in the base page are updated according to the leaf nodes, intermediate nodes and root nodes contained in the incremental page in order of version, so that all the tree nodes in the restored memory page can maintain the hash anchoring relationship from the leaf nodes to the intermediate nodes to the root nodes, such as storing the correct hash value of the lower tree nodes in the branch node slot, so as to realize the data verifiability.

[0202] It is mentioned before that the version of the incremental page can be the lowest or highest version in one or more memory pages corresponding to the incremental page. In the above example, the case that the version of the incremental page is the lowest version in the multiple memory pages corresponding to the incremental page is given. The case that the version of the incremental page is the highest version in the multiple memory pages corresponding to the incremental page is introduced below.

[0203] For the aforementioned case 2, i.e. the case where no base page with the same version is found in the persistent storage medium, the base page with the maximum version no greater than the read version, the same page ID and the base page type can be loaded from the persistent storage medium to the memory. On this basis, the increment page with the minimum version no less than the read version, the same page ID and the increment page type can also be loaded from the persistent storage medium to the memory. For example, the version to be found is 20, and there is no memory page with the version 20 in the memory, and of course no base page with the same version 20 is found in the persistent storage medium. In fact, there is BasePage1 with the version 17, DeltaPage1 with the version 19, DeltaPage2 with the version 21 and BasePage2 with the version 22 in the persistent storage medium. The DeltaPage1 with the version 19 can include the tree node with the version 18 and the tree node with the version 19, and the DeltaPage2 with the version 21 can include the tree node with the version 20 and the tree node with the version 21. The BasePage1 with the maximum version 17, the version no greater than 20, the same page ID and the base page type can be loaded to the memory, i.e. the version of this base page meeting the conditions is 17, and the DeltaPage1 with the version 19 and the DeltaPage2 with the version 21, the minimum version 21 no less than the read version 20, the same page ID and the increment page type, can be loaded to the memory. Then the loaded base page and increment page are played back to obtain the memory page.

[0204] For the case 2, in detail, the loaded base page and the loaded incremental pages can be replayed to get the memory page according to the page type and the version order. Still according to the example, the loaded base page is BasePage1 with version 17, and the loaded incremental pages include DeltaPage1 with version 19 and DeltaPage2 with version 21, then the incremental pages can be replayed according to the version order, i.e. on the basis of the BasePage1 with version 17, the incremental pages are replayed in the order of DeltaPage1 with version 19→ DeltaPage2 with version 21, to get the memory page. Since the DeltaPage2 with version 21 includes the tree node with version 20 and the tree node with version 21, when replaying the pages in order to the incremental page with the maximum version less than the read version, i.e. to the loaded DeltaPage1 with version 19, when replaying in order to the loaded incremental page with the maximum version 21, all the tree nodes in the DeltaPage2 are not replayed, but the tree nodes in the loaded incremental page with the maximum version are replayed in order until the same as the read version, i.e. the tree node with version 20 in the DeltaPage2 is replayed, to get the memory page.

[0205] S194: reading the state in the leaf node.

[0206] As mentioned before, the leaf node can be in the form of the data file as mentioned before, or in the form of the KVDB as mentioned before. For the form of the data file, the leaf node can include the position index of the state value in the data file in the persistent storage medium and the hash value of the state value content. Thus, the position index contained in the leaf node can be acquired, the position index points to the position in the data file in the persistent storage medium, and then the value at the position of the data file in the persistent storage medium pointed by the position index can be loaded into the memory and the state data therein can be read. For the form of the KVDB, the hash value of the leaf node can be used to find in the cache, if not in the cache, the state database module as shown in FIG. 7 can be used to find, which can involve binary search in the sst of each Level, as mentioned before, which will not be repeated here.

[0207] As mentioned before, the essence of a blockchain is a chain of blocks linked by hashes. A memory page can include all the states in the current version, many of which are likely to have been updated in a previous block and have continued to the current block without change. This is similar to Ethereum and is also referred to as the current state. The currentDB is used to store the latest "current state" data, such as the latest account state, contract code, and contract storage, etc. Moreover, as the blocks grow, the data in the currentDB can be constantly modified. The chain of blocks in the blockchain is linked in series, and building a global MPT tree of all states for each block is highly redundant. Referring to the same leaf node and intermediate node in the previous block that was last updated to the value is an efficient way of data storage. Moreover, the state that changes in each block is likely to be part of the global state. This is also similar to Ethereum and is also referred to as the history state.

[0208] In some implementations of current blockchain technology, there is a practice of storing the current state and the history state in the currentDB and the historyDB, respectively, and the two databases are usually independent entities. In some implementation schemes, both databases are independently persisted. However, this dual-database architecture has obvious defects: first, it leads to redundant storage of state data, thereby increasing storage overhead. For example, if the currentDB occupies 10 GB of disk space and the historyDB occupies 100 GB, the total storage requirement is 110 GB. Second, this architecture increases the complexity of the system. The usual operation process is to first update the currentDB, then generate a binary log (Binlog), then synchronize the Binlog to the historyDB, and finally execute the Binlog by the historyDB to generate the corresponding version of the state record. This mechanism for keeping the two databases synchronized not only increases the complexity of the system, but also can introduce potential risks of data consistency.

[0209] On the other hand, some blockchain implementations adopt a scheme that only retains the currentDB without maintaining the historyDB. This method greatly reduces the storage requirement (for example, only occupying 10 GB of disk space), but also brings new problems. When it is necessary to restore to a certain historical version of the state, if the read-write set is saved, the system needs to replay the read-write set in version order from the genesis block until the desired historical version state is reached; if the read-write set is not saved, it is necessary to replay all transactions from the genesis block until the target state is reached. This method is extremely inefficient when restoring the historical state, time-consuming and computationally intensive, especially when dealing with long-running blockchain systems, this problem becomes more prominent.

[0210] The present application provides a tree structure world state storage method based on the above-mentioned schemes of FIGS. 9-19, comprising:

[0211] S200: generating a corresponding memory page according to the divided logical page structure, the memory page being used to represent the content of all tree nodes in the logical page; the logical page is the result of aggregating a plurality of adjacent tree nodes according to the node association relationship of the tree structure, at least one tree node is contained in one logical page, and different tree nodes are contained in each different logical page.

[0212] S202: generating a base page and a delta page based on the changes of the contents of all tree nodes in the continuous version logical page;

[0213] S200 and S202 are similar to the foregoing and will not be described again.

[0214] S204: persisting the base page and the delta page in one database without distinguishing the currentDB and the historyDB.

[0215] In the present application, one database is set. When data is written to the disk, the historyDB and the currentDB are no longer distinguished, but the base page and the delta page are written into this one database. In this way, neither the currentDB and the historyDB two-database approach of the prior art is adopted, so that the data redundancy can be reduced, the storage overhead can be reduced, and the scheme of retaining only the currentDB without maintaining the historyDB of the prior art makes it faster and more efficient to restore any version state.

[0216] And, as mentioned earlier, the base page can be generated once for every predetermined number of state modifications, and the delta page can be generated once for every predetermined number of state modifications.

[0217] The base page and the delta page can contain a page identifier, and the page identifier includes a version, a page ID and a page type; the logical page and the memory page contain a page identifier, and the page identifier includes a version and a page ID.

[0218] Moreover, the state value can be stored in a data file of a persistent storage medium, and the state value includes a location index of the state value in the data file in the persistent storage medium in the leaf node.

[0219] The application further provides a method for restoring a world state of any version based on the above-mentioned schemes of the figures S200-S202, and the method comprises the following steps:

[0220] S210: reading a version to be restored;

[0221] S212: reading a base page of the same version as the version to be restored from the database;

[0222] S214: if the base page of the same version as the version to be restored is read from the database, loading the base page of the version to be restored from the database to the memory to obtain a memory page;

[0223] S216: if the base page of the same version as the version to be restored is not read from the database, loading a base page of a maximum version not greater than the version to be restored and a page type of the base page from the database to the memory, loading a delta page of a minimum version not less than the version to be restored and a page type of the delta page from the database to the memory after the version of the base page; and playing back the loaded base page and the delta page according to the page type and the version to obtain the memory page of the version to be restored;

[0224] S218: reading a state in the leaf node to the memory for the memory page containing the leaf node.

[0225] For restoring a world state of any version, for example, restoring a current version or any historical version, the above-mentioned restoring process can be performed according to the version to be restored. Of course, for the memory page existing in the memory, as mentioned above, based on the evicting mechanism in the cache, there can be a case that part of the MemoryPage is evicted. If the MemoryPage to be restored is evicted, the corresponding BasePage and DeltaPage can be read to replay the MemoryPage. As mentioned above, based on the change of the logical page of the continuous version, the base page and the delta page can be generated, and the base page and the delta page are the persistent objects of the memory page corresponding to the logical page. Therefore, for the case that the memory page does not exist in the memory, the corresponding base page and delta page can also be loaded from the persistent storage medium to the memory, and the loaded base page and delta page are played back to obtain the memory page.

[0226] In addition, when the blockchain node is cold started, there is generally no memory page in the memory. At this time, the current latest version block corresponding to the base page and the incremental page can be loaded into the memory from the persistent storage medium by the scheme of the present application, and the loaded base page and incremental page are played back to obtain the memory page, so as to obtain the current state.

[0227] In the prior art, to restore any historical version, in addition to the above-mentioned scheme of replaying all transactions from the genesis block until the target state is reached, the root node of the MPT tree locked by the state root of the specified historical version can be started, and the tree nodes in the database are searched. This process involves decoding and then searching the next level of tree nodes according to the slot relationship, and also involves searching layer by layer in LevelDB, including traversal and a large number of binary search operations. As described above, this is also a problem of calculation-intensive and read amplification. In fact, the same problem exists for restoring the current version.

[0228] The reading scheme provided in the present application can quickly find the base page and the incremental page in the database, thereby improving the recovery efficiency, because the base page and the incremental page are marked with versions.

[0229] The method can further include verifying the hash locking relationship between the upper and lower adjacent tree nodes from the leaf node to the root node, and verifying the consistency of the root node hash value with the state root in the latest version block. This is because the world state of the tree structure in the blockchain anchors the hash value of the next level tree node by the previous level tree node, thereby achieving verifiable storage as a whole. Therefore, after restoring the world state of a certain version by the above-mentioned method, further performing verification on the anchor hash can ensure the correctness of the world state.

[0230] As described above, the state value can be stored in a data file of the persistent storage medium, and the leaf node includes a position index of the state value in the data file of the persistent storage medium. Accordingly, reading the state in the leaf node herein can be to obtain the position index contained in the leaf node, the position index pointing to the position in the data file of the persistent storage medium, and then loading the value at the position of the data file in the persistent storage medium pointed by the position index into the memory and reading the state data therein.

[0231] As described previously, in one example, the leaf node can include a hash value of the state value content (valuehash), wherein the hash value of the leaf node is calculated based on the content in the leaf node, including based on the hash value of the state value content in the leaf node, but excluding the location index of the state value within the data file in the persistent storage medium. Here, based on the valuehash field included in the leaf node, the present scheme can also verify that the hash value of the data file in the persistent storage medium to which the location index points is consistent with the valuehash in the leaf node.

[0232] The loaded base page and the incremental page are played back in order of page type and version to obtain the memory page of the recovery version. Similar to the foregoing, based on the base page, the incremental page can be played back in order of version to the incremental page less than the maximum version of the recovery version, and the tree node in the loaded incremental page of the maximum version is continuously played back in order until the same as the recovery version, to obtain the memory page.

[0233] For example, if the version to be recovered is 20, and no base page with version 20 is found in the database, as in the foregoing example, BasePage1 with version no more than 20 and page type as base page, the maximum version of which is 17, can be loaded into the memory, i.e. the version of the base page meeting the condition here is 17, and DeltaPage1 with version 19 and page type as delta page, and DeltaPage2 with version 21, which are the minimum version no less than the read version 20 and have the same page ID, can be loaded into the memory after the version 17 of BasePage1, and then the loaded base page and delta page are played back to obtain the memory page. Specifically, the loaded base page and delta page can be played back to obtain the memory page in the order of page type and version. Still according to the foregoing example, the loaded base page is BasePage1 with version 17, and the loaded delta page includes DeltaPage1 with version 19 and DeltaPage2 with version 21, and then the delta page can be played back in the order of version, i.e. in the order of DeltaPage1 with version 19→DeltaPage2 with version 21, based on the BasePage1 with version 17, to obtain the memory page. Since DeltaPage2 with version 21 includes tree nodes with version 20 and tree nodes with version 21, when the page is played back in sequence to the maximum version of the delta page less than the read version, i.e. to the loaded DeltaPage1 with version 19, and then played back in sequence to the loaded maximum version 21 of DeltaPage2, all the tree nodes in the DeltaPage2 are not played back, but the tree nodes in the loaded maximum version of the delta page are continuously played back in sequence until the same as the read version, i.e. the tree nodes with version 20 in DeltaPage2 are played back, so as to obtain the memory page.

[0234] It should be noted that for multiple logical pages, although each predetermined number of state modifications generates a base page and each predetermined number of state modifications generates a delta page, the predetermined number is generally set to be the same, but different logical pages include different tree nodes, so for a tree structure including multiple logical pages, the tree nodes in different logical pages can not be modified synchronously. Thus, as shown in FIG. 20, the tree node with version 17 is located in the DeltaPage with version 17 in the left LogicalPage, and is located in the BasePage with version 17 in the right LogicalPage, i.e. the version numbers of BasePage and DeltaPage in different logical pages are not synchronous. When the world state of a specified version is recovered, the foregoing S214 and S216 can be parallel operations, and there is no sequence.

[0235] The application also provides a computer device, comprising:

[0236] a processor;

[0237] and a memory, wherein a program is stored in the memory, and when the processor executes the program, the operations of any one of the above methods are performed.

[0238] In the 1990s, it was quite obvious to distinguish whether an improvement in a technology was in hardware (e.g., improvement in circuit structures of diodes, transistors, switches, etc.) or in software (improvement in method flow). However, as technology has evolved, many improvements in method flow today can be considered as direct improvements in hardware circuit structures. Designers almost always obtain the corresponding hardware circuit structures by programming the improved method flow into hardware circuits. Therefore, it cannot be said that an improvement in a method flow cannot be implemented by hardware entity modules. For example, a programmable logic device (PLD) (e.g., a field programmable gate array (FPGA)) is an integrated circuit whose logic function is determined by user programming of the device. A digital system is "integrated" on a PLD by the designer programming it themselves, without having to ask a chip manufacturer to design and fabricate a custom integrated circuit chip. Moreover, instead of manually fabricating integrated circuit chips, this programming is now mostly implemented using "logic compiler" software, which is similar to software compilers used in program development, and the original code to be compiled is also written in a specific programming language, which is called a hardware description language (HDL), and there are many such languages, 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, RHDL (Ruby Hardware Description Language), etc., and the most commonly used are VHDL (Very-High-Speed Integrated Circuit Hardware Description Language) and Verilog. Those skilled in the art should be aware that, as long as the method flow is logically programmed in the above-mentioned hardware description languages and programmed into an integrated circuit, a hardware circuit that implements the logical method flow can be easily obtained.

[0239] The controller can be implemented in any suitable way, for example, the controller can take the form of, for example, a microprocessor or processor and a computer readable medium storing computer readable program code, such as software or firmware, executable by the (micro)processor, logic gates, switches, an application specific integrated circuit (ASIC), a programmable logic controller and an embedded microcontroller, examples of which include but are not limited to the following microcontrollers: ARC 625D, Atmel AT91SAM, Microchip PIC18F26K20 and Silicone Labs C8051F320, the memory controller can also be implemented as part of the control logic of the memory. The skilled person will also appreciate that, in addition to implementing the controller in pure computer readable program code, it is possible to implement the controller in the form of logic gates, switches, an application specific integrated circuit, a programmable logic controller and an embedded microcontroller, etc. to perform the same functions by logically programming the method steps. Such a controller can therefore be considered to be a hardware component, and the means included therein to perform the various functions can also be considered to be structures within the hardware component. Alternatively, or even additionally, the means to perform the various functions can be considered to be both a software module implementing the method and a structure within a hardware component.

[0240] The systems, apparatuses, modules or units illustrated by the above embodiments can be specifically implemented by computer chips or entities, or by products with certain functions. A typical implementation device is a server system. Of course, the present application does not rule out that with the development of future computer technologies, computers implementing the functions of the above embodiments can be personal computers, laptop computers, vehicle human-computer interaction devices, cellular phones, camera phones, smart phones, personal digital assistants, media players, navigation devices, electronic mail devices, game consoles, tablet computers, wearable devices, or combinations of any of these devices.

[0241] Although the method operational steps are provided in one or more embodiments in the specification as described in the embodiments or flowcharts, more or fewer operational steps can be included based on conventional or non-creative means. The order of the steps listed in the embodiments is only one of the many execution orders of the steps, and does not represent the only execution order. When the device or terminal product is executed in practice, the method order shown in the embodiments or the drawings can be executed in sequence or in parallel (for example, in a parallel processor or a multi-thread processing environment, or even in a distributed data processing environment). The terms "comprise", "contain" or any other variant thereof are intended to cover non-exclusive inclusion, so that a process, method, product or device including a series of elements not only includes those elements, but also includes other elements not explicitly listed or inherent to such a process, method, product or device. Without more limitations, it does not exclude the presence of other same or equivalent elements in the process, method, product or device including the elements. For example, if the first, second, etc. terms are used to represent names, they do not represent any particular order.

[0242] For the convenience of description, the above device is described as various modules described in function. Of course, when implementing one or more of the present specification, the functions of each module can be implemented in the same or more software and / or hardware, or modules implementing the same function can be implemented by a combination of multiple sub-modules or sub-units. The above described device embodiments are only illustrative, for example, the division of the units is only a logical function division, and actual implementation can have another division method, for example, multiple units or components can be combined or integrated into another system, or some features can be ignored or not executed. Another point, the coupling or direct coupling or communication connection between the displayed or discussed each other can be through some interface, indirect coupling or communication connection between devices or units, which can be electrical, mechanical or other forms.

[0243] The present application is described with reference to flowcharts and / or block diagrams of methods, devices (systems), and computer program products according to embodiments of the present application. It should be understood that each flow and / or block in the flowchart and / or block diagram, and the combination of flows and / or blocks in the flowchart and / or block diagram can be implemented by computer program instructions. These computer program instructions can be provided to the processor of a general-purpose computer, a special-purpose computer, an embedded processor, or other programmable data processing devices to produce a machine, so that the instructions executed by the processor of the computer or other programmable data processing devices produce the device for implementing the functions specified in one or more flows or blocks of the flowchart and / or block diagram.

[0244] These computer program instructions can also be stored in a computer- readable memory that can direct a computer or other programmable data processing apparatus to function in a particular manner, such that the instructions stored in the computer-readable memory produce an article of manufacture including instructions which implement the function specified in the flowchart or flowsheets and / or block or blocks of the block diagrams.

[0245] These computer program instructions can 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 the flowchart or flowsheets and / or block or blocks of the block diagrams.

[0246] In one typical configuration, the computing device includes one or more processors (CPUs), input / output interfaces, network interfaces, and memory.

[0247] The memory can include non-persistent memory and / or volatile memory, such as random access memory (RAM) about which the computer stores the information. The memory is an example of computer readable media.

[0248] Computer readable media includes permanent and non-permanent, removable and non-removable media implemented in any method or technology for storage of information such as 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 technology, compact disc read only memory (CD-ROM), digital versatile disc (DVD), or other optical storage, magnetic cassettes, magnetic tapes, magnetic disk storage, graphene storage or other magnetic storage devices, or any other non-transmission medium that can be used to store information accessible to computing devices. According to the definition herein, computer readable media does not include transitory media, such as modulated data signals and carrier waves.

[0249] Those skilled in the art will appreciate that the one or more embodiments described herein can be provided as a method, a system or a computer program product. Accordingly, the one or more embodiments described herein can take the form of an entirely hardware embodiment, an entirely software embodiment or an embodiment combining software and hardware aspects. Furthermore, the one or more embodiments described herein can take the form of a computer program product on one or more computer-usable storage media (including, but not limited to, disk storage, CD-ROMs, optical storage devices, etc.) embodying computer readable code.

[0250] The one or more embodiments described herein can be described in the general context of computer-executable instructions, such as program modules, being executed by a computer. Generally, program modules include routines, programs, objects, components, data structures, etc., that perform particular tasks or implement particular abstract data types. The one or more embodiments described herein can also be practiced in distributed computing environments where tasks are performed by remote processing devices that are linked through a communications network. In a distributed computing environment, program modules can be located in both local and remote computer storage media including memory storage devices.

[0251] The various embodiments described in this specification can be described in the general context of computer-executable instructions, such as program modules, being executed by a computer. Generally, program modules include routines, programs, objects, components, data structures, etc., that perform particular tasks or implement particular abstract data types. The various embodiments described in this specification can also be practiced in distributed computing environments where tasks are performed by remote processing devices that are linked through a communications network. In a distributed computing environment, program modules can be located in both local and remote computer storage media including memory storage devices.

[0252] The above description is only some embodiments of the one or more embodiments described in this specification and is not intended to limit the one or more embodiments described in this specification. The one or more embodiments described in this specification can have various modifications and changes for those skilled in the art. Any modifications, equivalent replacements, improvements, etc. made within the spirit and principle of the specification shall be included in the scope of claims. < / k2-v2> < / k1-v1> < / k2-v2> < / k1-v1> < / k2-v2> < / k1-v1> < / k2-v2> < / k1-v1>

Claims

A method for storing a tree-structured world state, comprising: generating a corresponding memory page from the generated / updated tree node according to the divided logical page structure, the memory page being used to represent the content of all tree nodes in the corresponding logical page; the logical page being a result of aggregating a plurality of adjacent tree nodes according to the node association relationship in the tree structure, at least one tree node being contained in one logical page, and different tree nodes being contained in different logical pages; generating a base page and a delta page based on the change of the content of all tree nodes in the continuous version logical page; persisting the base page and the delta page in a database without distinguishing between a current DB and a history DB. The method of claim 1, further comprising: generating a base page once for every predetermined number of state modifications. The method of claim 1, further comprising: generating a delta page once for every predetermined number of state modifications. The method according to any one of claims 1-3, wherein the base page and the delta page contain a page identifier, and the page identifier comprises a version, a page ID, and a page type; and the logical page and the memory page contain a page identifier, and the page identifier comprises a version and a page ID. The method according to any one of claims 1-3, wherein the base page and the delta page are stored in the database in a version order. The method according to any one of claims 1-3, wherein the state value is stored in a data file of a persistent storage medium, and a location index of the state value in the data file of the persistent storage medium is contained in a leaf node. A method for restoring a world state of any version from a database stored based on any one of claims 1-6, comprising: reading a version to be restored; reading a base page of the same version as the restored version from the database; if the base page of the same version as the restored version is read from the database, loading the base page of the restored version from the database to a memory to obtain a memory page; if the base page of the same version as the restored version is not read from the database, loading a base page of a maximum version not greater than the restored version and of a base page type from the database to the memory, and loading a delta page of a minimum version not less than the restored version and of a delta page type from the database to the memory after the version of the base page; playing back the loaded base page and the delta page in a page type and version order to obtain the memory page of the restored version; for a memory page containing a leaf node, reading the state in the leaf node to the memory. The method according to claim 7, further comprising: verifying the hash locking relationship between the adjacent tree nodes in a direction from a leaf node to a root node, and verifying the consistency of the root node hash value with the state root in the latest version block. The method according to claim 7, wherein the reading of the state in the leaf node comprises: obtaining a location index contained in the leaf node, the location index pointing to a location in a data file of a persistent storage medium; loading the value at the location in the data file of the persistent storage medium pointed to by the location index to the memory and reading the state data therein. The method of claim 9, wherein the leaf node comprises a valuehash field for storing a hash value of a data file in the persistent storage medium, the method further comprising: verifying that the hash value of the data file in the persistent storage medium pointed by the location index is consistent with the valuehash in the leaf node. The method of claim 7, wherein the replaying the loaded base page and the incremental pages in order of page type and version to obtain the memory page of the recovery version comprises: based on the base page, replaying the incremental pages in order of version to an incremental page smaller than a maximum version of the recovery version, and continuing to replay the tree node in the loaded incremental page of the maximum version in order until the same as the recovery version to obtain the memory page. The method of claim 7, wherein the any version comprises a current version and any historical version. A computer device comprising: a processor; and a memory having stored therein a program, wherein the processor, when executing the program, performs the operations of any one of claims 1-12.

Citation Information

Patent Citations

  • State data storage method, state data query method, data management method, equipment and storage medium

    CN110442577A

  • Storage method and recovery method of world state of tree structure and computer equipment

    CN118797105A

  • Method for searching basic page / incremental page and computer equipment

    CN118860288A

  • Method for scaling leaf page / middle page and computer equipment

    CN118964351A

  • Method for searching basic page and / or incremental page and computer equipment

    CN119415010A

Cited By

  • Tree node linkage department associated piece counting data integrated query method and system

    CN121764976A