@nomicfoundation/ethereumjs-trie
Advanced tools
Comparing version 5.0.5 to 6.0.0
@@ -19,3 +19,3 @@ /// <reference types="node" /> | ||
* | ||
* - Two edge elements proof. In this case two existent or non-existent proof(fisrt and last) should be provided. | ||
* - Two edge elements proof. In this case two existent or non-existent proof(first and last) should be provided. | ||
* | ||
@@ -22,0 +22,0 @@ * NOTE: Currently only supports verification when the length of firstKey and lastKey are the same. |
@@ -359,3 +359,3 @@ "use strict"; | ||
* | ||
* - Two edge elements proof. In this case two existent or non-existent proof(fisrt and last) should be provided. | ||
* - Two edge elements proof. In this case two existent or non-existent proof(first and last) should be provided. | ||
* | ||
@@ -362,0 +362,0 @@ * NOTE: Currently only supports verification when the length of firstKey and lastKey are the same. |
@@ -13,4 +13,2 @@ /// <reference types="node" /> | ||
* The basic trie interface, use with `import { Trie } from '@nomicfoundation/ethereumjs-trie'`. | ||
* In Ethereum applications stick with the {@link SecureTrie} overlay. | ||
* The API for the base and the secure interface are about the same. | ||
*/ | ||
@@ -27,4 +25,6 @@ export declare class Trie { | ||
/** | ||
* Create a new trie | ||
* Creates a new trie. | ||
* @param opts Options for instantiating the trie | ||
* | ||
* Note: in most cases, the static {@link Trie.create} constructor should be used. It uses the same API but provides sensible defaults | ||
*/ | ||
@@ -106,3 +106,3 @@ constructor(opts?: TrieOpts); | ||
* @param stack - a stack of nodes to the value given by the key | ||
* @param opStack - a stack of levelup operations to commit at the end of this funciton | ||
* @param opStack - a stack of levelup operations to commit at the end of this function | ||
*/ | ||
@@ -109,0 +109,0 @@ _saveStack(key: Nibbles, stack: TrieNode[], opStack: BatchDBOp[]): Promise<void>; |
@@ -16,9 +16,9 @@ "use strict"; | ||
* The basic trie interface, use with `import { Trie } from '@nomicfoundation/ethereumjs-trie'`. | ||
* In Ethereum applications stick with the {@link SecureTrie} overlay. | ||
* The API for the base and the secure interface are about the same. | ||
*/ | ||
class Trie { | ||
/** | ||
* Create a new trie | ||
* Creates a new trie. | ||
* @param opts Options for instantiating the trie | ||
* | ||
* Note: in most cases, the static {@link Trie.create} constructor should be used. It uses the same API but provides sensible defaults | ||
*/ | ||
@@ -496,3 +496,3 @@ constructor(opts) { | ||
if (branchNodes.length === 1) { | ||
// add the one remaing branch node to node above it | ||
// add the one remaining branch node to node above it | ||
const branchNode = branchNodes[0][1]; | ||
@@ -520,3 +520,3 @@ const branchNodeKey = branchNodes[0][0]; | ||
else { | ||
// simple removing a leaf and recaluclation the stack | ||
// simple removing a leaf and recalculation the stack | ||
if (parentNode) { | ||
@@ -534,3 +534,3 @@ stack.push(parentNode); | ||
* @param stack - a stack of nodes to the value given by the key | ||
* @param opStack - a stack of levelup operations to commit at the end of this funciton | ||
* @param opStack - a stack of levelup operations to commit at the end of this function | ||
*/ | ||
@@ -698,5 +698,5 @@ async _saveStack(key, stack, opStack) { | ||
async verifyPrunedIntegrity() { | ||
const root = this.root().toString('hex'); | ||
const roots = [this.root().toString('hex'), this.appliedKey(types_1.ROOT_DB_KEY).toString('hex')]; | ||
for (const dbkey of this._db.db._database.keys()) { | ||
if (dbkey === root) { | ||
if (roots.includes(dbkey)) { | ||
// The root key can never be found from the trie, otherwise this would | ||
@@ -703,0 +703,0 @@ // convert the tree from a directed acyclic graph to a directed cycling graph |
{ | ||
"name": "@nomicfoundation/ethereumjs-trie", | ||
"version": "5.0.5", | ||
"version": "6.0.0", | ||
"description": "This is an implementation of the modified merkle patricia tree as specified in Ethereum's yellow paper.", | ||
@@ -47,4 +47,5 @@ "keywords": [ | ||
"dependencies": { | ||
"@nomicfoundation/ethereumjs-rlp": "4.0.3", | ||
"@nomicfoundation/ethereumjs-util": "8.0.6", | ||
"@nomicfoundation/ethereumjs-rlp": "5.0.0", | ||
"@nomicfoundation/ethereumjs-util": "9.0.0", | ||
"@types/readable-stream": "^2.3.13", | ||
"ethereum-cryptography": "0.1.3", | ||
@@ -56,3 +57,2 @@ "readable-stream": "^3.6.0" | ||
"@types/benchmark": "^1.0.33", | ||
"@types/readable-stream": "^2.3.13", | ||
"abstract-level": "^1.0.3", | ||
@@ -59,0 +59,0 @@ "level": "^8.0.0", |
@@ -31,3 +31,3 @@ # @ethereumjs/trie | ||
An additional `CheckpointTrie` implementation adds checkpointing functionality to `Trie` through the methods `checkpoint`, `commit` and `revert`. | ||
Checkpointing functionality to `Trie` through the methods `checkpoint`, `commit` and `revert`. | ||
@@ -39,6 +39,5 @@ It is best to select the variant that is most appropriate for your unique use case. | ||
```typescript | ||
import { Trie, LevelDB } from '@ethereumjs/trie' | ||
import { Level } from 'level' | ||
import { Trie, MapDB } from '@ethereumjs/trie' | ||
const trie = new Trie({ db: new LevelDB(new Level('MY_TRIE_DB_LOCATION')) }) | ||
const trie = new Trie({ db: new MapDB() }) | ||
@@ -54,38 +53,34 @@ async function test() { | ||
You can also review our [examples](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/trie/examples) for database implementations. The [level.js](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/trie/examples/level.js) example is the default implementation while [lmdb.js](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/trie/examples/lmdb.js) is an alternative implementation that uses the popular [LMDB](https://en.wikipedia.org/wiki/Lightning_Memory-Mapped_Database) as its underlying database. | ||
### Use with static constructor | ||
> If no `db` option is provided, an in-memory database powered by [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) will fulfill this role. | ||
```typescript | ||
import { Trie, MapDB } from '@ethereumjs/trie' | ||
### Database | ||
const trie = Trie.create() | ||
> By default the only supported database is LevelDB via the `level` module. | ||
async function test() { | ||
await trie.put(Buffer.from('test'), Buffer.from('one')) | ||
const value = await trie.get(Buffer.from('test')) | ||
console.log(value.toString()) // 'one' | ||
} | ||
The 5.0.0 release introduced the `DB` interface to allow for the decoupling of the database layer from the previously tightly-coupled `LevelDB` integration. The `DB` interface defines the methods `get`, `put`, `del`, `batch` and `copy` that a concrete implementation of the `DB` interface will need to implement. The default implementation of the `DB` interface is now an in-memory storage based on the native [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) and functions identically to pre-5.0.0 releases. | ||
test() | ||
``` | ||
The base trie implementation (`Trie`) as well as all subclass implementations (`CheckpointTrie` and `SecureTrie`) accept any database implementation that adheres to the `DB` interface as the `db` option. It is possible to use alternative implementations like [LevelDB](#leveldb) if you wish to. | ||
When the static `Trie.create` constructor is used without any options, the `trie` object is instantiated with defaults configured to match the Etheruem production spec (i.e. keys are hashed using SHA256). It also persists the state root of the tree on each write operation, ensuring that your trie remains in the state you left it when you start your application the next time. | ||
#### Node Deletion | ||
### `Trie` Configuration Options | ||
By default, the deletion of trie nodes from the underlying database does not occur in order to avoid corrupting older trie states (as of `v4.2.0`). Should you only wish to work with the latest state of a trie, you can switch to a delete behavior (for example, if you wish to save disk space) by using the `deleteFromDB` constructor option (see related release notes in the changelog for further details). | ||
#### Database Options | ||
#### Persistence | ||
The `DB` opt in the `TrieOpts` allows you to use any database that conforms to the `DB` interface to store the trie data in. We provide several [examples](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/trie/examples) for database implementations. The [level.js](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/trie/examples/level.js) example is used in the `ethereumjs client` while [lmdb.js](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/trie/examples/lmdb.js) is an alternative implementation that uses the popular [LMDB](https://en.wikipedia.org/wiki/Lightning_Memory-Mapped_Database) as its underlying database. | ||
You can enable persistence by setting the `useRootPersistence` option to `true` when constructing a trie through the `Trie.create` function. As such, this value is preserved when creating copies of the trie and is incapable of being modified once a trie is instantiated. | ||
If no `db` option is provided, an in-memory database powered by [a Javascript Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) will fulfill this role. | ||
```typescript | ||
import { Trie, LevelDB } from '@ethereumjs/trie' | ||
import { Level } from 'level' | ||
If you want to use an alternative database, you can integrate your own by writing a DB wrapper that conforms to the [`DB` interface](./src/types.ts#L85). The `DB` interface defines the methods `get`, `put`, `del`, `batch` and `copy` that a concrete implementation of the `DB` interface will need to implement. | ||
const trie = await Trie.create({ | ||
db: new LevelDB(new Level('MY_TRIE_DB_LOCATION')), | ||
useRootPersistence: true, | ||
}) | ||
``` | ||
##### LevelDB | ||
The `Trie.create` function is asynchronous and will read the root from your database before returning the trie instance. If you don't have the need for automatic restoration of the root then you can use the `new Trie` constructor with the same options and get persistence without the automatic restoration. | ||
As an example, to leveage `LevelDB` for all operations then you should create a file with the [following implementation from our recipes](./recipes//level.ts) in your project. Then instantiate your DB and trie as below: | ||
#### LevelDB | ||
If you wish to continue to rely on `LevelDB` for all operations then you should create a file with the [following implementation from our recipes](./recipes//level.ts) in your project. It is then possible to use the `LevelDB` implementation as follows: | ||
```typescript | ||
@@ -100,2 +95,19 @@ import { Trie } from '@ethereumjs/trie' | ||
#### Node Deletion (Pruning) | ||
By default, the deletion of trie nodes from the underlying database does not occur in order to avoid corrupting older trie states (as of `v4.2.0`). Should you only wish to work with the latest state of a trie, you can switch to a delete behavior (for example, if you wish to save disk space) by using the `deleteFromDB` constructor option (see related release notes in the changelog for further details). | ||
#### Root Persistence | ||
You can enable persistence by setting the `useRootPersistence` option to `true` when constructing a trie through the `Trie.create` function. As such, this value is preserved when creating copies of the trie and is incapable of being modified once a trie is instantiated. | ||
```typescript | ||
import { Trie, MapDB } from '@ethereumjs/trie' | ||
const trie = await Trie.create({ | ||
db: new MapDB(), | ||
useRootPersistence: true, | ||
}) | ||
``` | ||
## Proofs | ||
@@ -175,2 +187,4 @@ | ||
import { LevelDB } from './your-level-implementation' | ||
// Set stateRoot to block #222 | ||
@@ -201,2 +215,4 @@ const stateRoot = '0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544' | ||
import { LevelDB } from './your-level-implementation' | ||
const stateRoot = 'STATE_ROOT_OF_A_BLOCK' | ||
@@ -203,0 +219,0 @@ |
@@ -398,3 +398,3 @@ import { BranchNode, ExtensionNode, LeafNode, Trie } from '../trie' | ||
* | ||
* - Two edge elements proof. In this case two existent or non-existent proof(fisrt and last) should be provided. | ||
* - Two edge elements proof. In this case two existent or non-existent proof(first and last) should be provided. | ||
* | ||
@@ -401,0 +401,0 @@ * NOTE: Currently only supports verification when the length of firstKey and lastKey are the same. |
@@ -35,4 +35,2 @@ import { RLP_EMPTY_STRING, arrToBufArr } from '@nomicfoundation/ethereumjs-util' | ||
* The basic trie interface, use with `import { Trie } from '@nomicfoundation/ethereumjs-trie'`. | ||
* In Ethereum applications stick with the {@link SecureTrie} overlay. | ||
* The API for the base and the secure interface are about the same. | ||
*/ | ||
@@ -57,4 +55,6 @@ export class Trie { | ||
/** | ||
* Create a new trie | ||
* Creates a new trie. | ||
* @param opts Options for instantiating the trie | ||
* | ||
* Note: in most cases, the static {@link Trie.create} constructor should be used. It uses the same API but provides sensible defaults | ||
*/ | ||
@@ -567,3 +567,3 @@ constructor(opts?: TrieOpts) { | ||
if (branchNodes.length === 1) { | ||
// add the one remaing branch node to node above it | ||
// add the one remaining branch node to node above it | ||
const branchNode = branchNodes[0][1] | ||
@@ -598,3 +598,3 @@ const branchNodeKey = branchNodes[0][0] | ||
} else { | ||
// simple removing a leaf and recaluclation the stack | ||
// simple removing a leaf and recalculation the stack | ||
if (parentNode) { | ||
@@ -614,3 +614,3 @@ stack.push(parentNode) | ||
* @param stack - a stack of nodes to the value given by the key | ||
* @param opStack - a stack of levelup operations to commit at the end of this funciton | ||
* @param opStack - a stack of levelup operations to commit at the end of this function | ||
*/ | ||
@@ -807,5 +807,5 @@ async _saveStack(key: Nibbles, stack: TrieNode[], opStack: BatchDBOp[]): Promise<void> { | ||
async verifyPrunedIntegrity(): Promise<boolean> { | ||
const root = this.root().toString('hex') | ||
const roots = [this.root().toString('hex'), this.appliedKey(ROOT_DB_KEY).toString('hex')] | ||
for (const dbkey of (<any>this)._db.db._database.keys()) { | ||
if (dbkey === root) { | ||
if (roots.includes(dbkey)) { | ||
// The root key can never be found from the trie, otherwise this would | ||
@@ -812,0 +812,0 @@ // convert the tree from a directed acyclic graph to a directed cycling graph |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
262112
10
336
5
+ Added@chainsafe/as-sha256@0.3.1(transitive)
+ Added@chainsafe/persistent-merkle-tree@0.5.0(transitive)
+ Added@chainsafe/ssz@0.10.2(transitive)
+ Added@nomicfoundation/ethereumjs-rlp@5.0.0(transitive)
+ Added@nomicfoundation/ethereumjs-util@9.0.0(transitive)
+ Added@types/readable-stream@2.3.15(transitive)
+ Addedsafe-buffer@5.1.2(transitive)
- Removed@nomicfoundation/ethereumjs-rlp@4.0.3(transitive)
- Removed@nomicfoundation/ethereumjs-util@8.0.6(transitive)