diff --git a/benchmarks/checkpointing.ts b/benchmarks/checkpointing.ts index ac7a32a..fed93ed 100644 --- a/benchmarks/checkpointing.ts +++ b/benchmarks/checkpointing.ts @@ -4,42 +4,37 @@ import { CheckpointTrie } from '../dist' const iterations = 500 const samples = 20 -const iterTest = async (numOfIter: number): Promise> => { - return new Promise(async (resolve) => { - let vals = [] as any - let keys = [] as any - - for (let i = 0; i <= numOfIter; i++) { - vals.push(pseudoRandomBytes(32)) - keys.push(pseudoRandomBytes(32)) - } - - let hrstart = process.hrtime() - let numOfOps = 0 - let trie = new CheckpointTrie() - - for (let i = 0; i < numOfIter; i++) { - await trie.put(vals[i], keys[i]) - trie.checkpoint() - await trie.get(Buffer.from('test')) - numOfOps++ - if (numOfOps === numOfIter) { - const hrend = process.hrtime(hrstart) - resolve(hrend) - } - } - }) +const iterTest = (numOfIter: number): [number, number] | undefined => { + let vals = [] as any + let keys = [] as any + + for (let i = 0; i <= numOfIter; i++) { + vals.push(pseudoRandomBytes(32)) + keys.push(pseudoRandomBytes(32)) + } + + let hrstart = process.hrtime() + let trie = new CheckpointTrie() + + for (let i = 0; i < numOfIter; i++) { + trie.put(vals[i], keys[i]) + trie.checkpoint() + trie.get(Buffer.from('test')) + } + + const hrend = process.hrtime(hrstart) + return hrend } -const go = async () => { +const go = () => { let i = 0 let avg = [0, 0] while (i <= samples) { - const hrend = await iterTest(iterations) - avg[0] += hrend[0] - avg[1] += hrend[1] - // console.log('benchmarks/checkpointing.ts | execution time: %ds %dms', hrend[0], (hrend[1] / 1000000).toFixed(3)) + const hrend = iterTest(iterations) + avg[0] += hrend![0] + avg[1] += hrend![1] + // console.log('benchmarks/checkpointing.ts | execution time: %ds %dms', hrend![0], (hrend![1] / 1000000).toFixed(3)) i++ } console.log( diff --git a/benchmarks/random.ts b/benchmarks/random.ts index 9f5ab6f..0b5c7bf 100644 --- a/benchmarks/random.ts +++ b/benchmarks/random.ts @@ -10,7 +10,7 @@ const ERA_SIZE = 1000 const trie = new BaseTrie() let seed = Buffer.alloc(32).fill(0) -const run = async (): Promise => { +const run = () => { let i = 0 while (i <= ROUNDS) { seed = keccak256(seed) @@ -22,11 +22,11 @@ const run = async (): Promise => { } if (SYMMETRIC) { - await trie.put(seed, seed) + trie.put(seed, seed) genRoot() } else { const val = keccak256(seed) - await trie.put(seed, val) + trie.put(seed, val) genRoot() } @@ -34,12 +34,12 @@ const run = async (): Promise => { } } -const go = async () => { +const go = () => { const testName = `benchmarks/random.ts | rounds: ${ROUNDS}, ERA_SIZE: ${ERA_SIZE}, ${ SYMMETRIC ? 'sys' : 'rand' }` console.time(testName) - await run() + run() console.timeEnd(testName) } diff --git a/docs/classes/_basetrie_.trie.md b/docs/classes/_basetrie_.trie.md index ab26256..6e802ef 100644 --- a/docs/classes/_basetrie_.trie.md +++ b/docs/classes/_basetrie_.trie.md @@ -2,12 +2,12 @@ # Class: Trie -Use `import { BaseTrie as Trie } from 'merkle-patricia-tree'` for the base interface. -In Ethereum applications stick with the Secure Trie Overlay `import { SecureTrie } from 'merkle-patricia-tree'`. +Use `import { BaseTrie } from 'merkle-patricia-tree'` for the base interface. +In Ethereum applications use the Secure Trie Overlay: `import { SecureTrie } from 'merkle-patricia-tree'`. The API for the base and the secure interface are about the same. -**`param`** A [levelup](https://github.com/Level/levelup) instance. By default creates an in-memory [memdown](https://github.com/Level/memdown) instance. -If the db is `null` or left undefined, then the trie will be stored in memory via [memdown](https://github.com/Level/memdown) +**`param`** You may pass in a [levelup](https://github.com/Level/levelup) instance to get loaded into memory. +If the db is `null` or left undefined, then the trie will be stored via an in-memory JavaScript map. **`param`** A `Buffer` for the root of a previously stored trie @@ -41,17 +41,15 @@ If the db is `null` or left undefined, then the trie will be stored in memory vi * [_createInitialNode](_basetrie_.trie.md#_createinitialnode) * [_deleteNode](_basetrie_.trie.md#_deletenode) * [_findDbNodes](_basetrie_.trie.md#_finddbnodes) -* [_findValueNodes](_basetrie_.trie.md#_findvaluenodes) -* [_formatNode](_basetrie_.trie.md#_formatnode) +* [_formatNode](_basetrie_.trie.md#private-_formatnode) * [_lookupNode](_basetrie_.trie.md#_lookupnode) * [_putNode](_basetrie_.trie.md#_putnode) * [_saveStack](_basetrie_.trie.md#private-_savestack) * [_updateNode](_basetrie_.trie.md#private-_updatenode) -* [_walkTrie](_basetrie_.trie.md#_walktrie) +* [_walkTrie](_basetrie_.trie.md#private-_walktrie) * [batch](_basetrie_.trie.md#batch) * [checkRoot](_basetrie_.trie.md#checkroot) * [copy](_basetrie_.trie.md#copy) -* [createReadStream](_basetrie_.trie.md#createreadstream) * [del](_basetrie_.trie.md#del) * [findPath](_basetrie_.trie.md#findpath) * [get](_basetrie_.trie.md#get) @@ -65,15 +63,15 @@ If the db is `null` or left undefined, then the trie will be stored in memory vi ### constructor -\+ **new Trie**(`db?`: LevelUp | null, `root?`: Buffer): *[Trie](_basetrie_.trie.md)* +\+ **new Trie**(`db?`: LevelUp | DBMap | null, `root?`: Buffer): *[Trie](_basetrie_.trie.md)* -*Defined in [baseTrie.ts:42](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L42)* +*Defined in [baseTrie.ts:43](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L43)* **Parameters:** Name | Type | ------ | ------ | -`db?` | LevelUp | null | +`db?` | LevelUp | DBMap | null | `root?` | Buffer | **Returns:** *[Trie](_basetrie_.trie.md)* @@ -84,7 +82,7 @@ Name | Type | • **EMPTY_TRIE_ROOT**: *Buffer* -*Defined in [baseTrie.ts:39](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L39)* +*Defined in [baseTrie.ts:41](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L41)* ___ @@ -92,7 +90,7 @@ ___ • **db**: *DB* -*Defined in [baseTrie.ts:40](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L40)* +*Defined in [baseTrie.ts:42](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L42)* ## Accessors @@ -100,13 +98,13 @@ ___ • **get root**(): *Buffer* -*Defined in [baseTrie.ts:100](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L100)* +*Defined in [baseTrie.ts:108](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L108)* **Returns:** *Buffer* • **set root**(`value`: Buffer): *void* -*Defined in [baseTrie.ts:96](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L96)* +*Defined in [baseTrie.ts:104](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L104)* **Parameters:** @@ -120,9 +118,11 @@ Name | Type | ### _createInitialNode -▸ **_createInitialNode**(`key`: Buffer, `value`: Buffer): *Promise‹void›* +▸ **_createInitialNode**(`key`: Buffer, `value`: Buffer): *void* -*Defined in [baseTrie.ts:651](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L651)* +*Defined in [baseTrie.ts:596](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L596)* + +Creates the initial node from an empty tree **Parameters:** @@ -131,15 +131,15 @@ Name | Type | `key` | Buffer | `value` | Buffer | -**Returns:** *Promise‹void›* +**Returns:** *void* ___ ### _deleteNode -▸ **_deleteNode**(`k`: Buffer, `stack`: TrieNode[]): *Promise‹void›* +▸ **_deleteNode**(`k`: Buffer, `stack`: TrieNode[]): *void* -*Defined in [baseTrie.ts:529](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L529)* +*Defined in [baseTrie.ts:474](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L474)* **Parameters:** @@ -148,66 +148,52 @@ Name | Type | `k` | Buffer | `stack` | TrieNode[] | -**Returns:** *Promise‹void›* +**Returns:** *void* ___ ### _findDbNodes -▸ **_findDbNodes**(`onFound`: FoundNode): *Promise‹void›* - -*Defined in [baseTrie.ts:279](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L279)* - -**Parameters:** +▸ **_findDbNodes**(): *FoundNode[]* -Name | Type | ------- | ------ | -`onFound` | FoundNode | +*Defined in [baseTrie.ts:258](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L258)* -**Returns:** *Promise‹void›* +**Returns:** *FoundNode[]* ___ -### _findValueNodes - -▸ **_findValueNodes**(`onFound`: FoundNode): *Promise‹void›* - -*Defined in [baseTrie.ts:257](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L257)* - -**Parameters:** - -Name | Type | ------- | ------ | -`onFound` | FoundNode | +### `Private` _formatNode -**Returns:** *Promise‹void›* +▸ **_formatNode**(`node`: TrieNode, `topLevel`: boolean, `opStack`: BatchDBOp[], `remove`: boolean): *Buffer | null | Buffer‹› | Buffer‹›[][]* -___ +*Defined in [baseTrie.ts:612](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L612)* -### _formatNode +Formats node to be saved by db.batch. -▸ **_formatNode**(`node`: TrieNode, `topLevel`: boolean, `opStack`: BatchDBOp[], `remove`: boolean): *Buffer | null | Buffer‹› | Buffer‹›[][]* - -*Defined in [baseTrie.ts:659](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L659)* +**`method`** _formatNode **Parameters:** -Name | Type | Default | ------- | ------ | ------ | -`node` | TrieNode | - | -`topLevel` | boolean | - | -`opStack` | BatchDBOp[] | - | -`remove` | boolean | false | +Name | Type | Default | Description | +------ | ------ | ------ | ------ | +`node` | TrieNode | - | the node to format | +`topLevel` | boolean | - | if the node is at the top level | +`opStack` | BatchDBOp[] | - | the opStack to push the node's data | +`remove` | boolean | false | whether to remove the node (only used for CheckpointTrie) | **Returns:** *Buffer | null | Buffer‹› | Buffer‹›[][]* +- the node's hash used as the key or the rawNode + ___ ### _lookupNode -▸ **_lookupNode**(`node`: Buffer | Buffer[]): *Promise‹TrieNode | null›* +▸ **_lookupNode**(`node`: Buffer | Buffer[]): *TrieNode | null* + +*Defined in [baseTrie.ts:174](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L174)* -*Defined in [baseTrie.ts:172](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L172)* +Retrieves a node from db by hash **Parameters:** @@ -215,15 +201,17 @@ Name | Type | ------ | ------ | `node` | Buffer | Buffer[] | -**Returns:** *Promise‹TrieNode | null›* +**Returns:** *TrieNode | null* ___ ### _putNode -▸ **_putNode**(`node`: TrieNode): *Promise‹void›* +▸ **_putNode**(`node`: TrieNode): *void* -*Defined in [baseTrie.ts:190](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L190)* +*Defined in [baseTrie.ts:192](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L192)* + +Writes a single node to db **Parameters:** @@ -231,15 +219,15 @@ Name | Type | ------ | ------ | `node` | TrieNode | -**Returns:** *Promise‹void›* +**Returns:** *void* ___ ### `Private` _saveStack -▸ **_saveStack**(`key`: number[], `stack`: TrieNode[], `opStack`: BatchDBOp[]): *Promise‹void›* +▸ **_saveStack**(`key`: Nibbles, `stack`: TrieNode[], `opStack`: BatchDBOp[]): *void* -*Defined in [baseTrie.ts:500](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L500)* +*Defined in [baseTrie.ts:445](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L445)* saves a stack @@ -249,19 +237,19 @@ saves a stack Name | Type | Description | ------ | ------ | ------ | -`key` | number[] | the key. Should follow the stack | +`key` | Nibbles | the key. Should follow the stack | `stack` | TrieNode[] | a stack of nodes to the value given by the key | -`opStack` | BatchDBOp[] | a stack of levelup operations to commit at the end of this funciton | +`opStack` | BatchDBOp[] | a stack of levelup operations to commit at the end of this funciton | -**Returns:** *Promise‹void›* +**Returns:** *void* ___ ### `Private` _updateNode -▸ **_updateNode**(`k`: Buffer, `value`: Buffer, `keyRemainder`: number[], `stack`: TrieNode[]): *Promise‹void›* +▸ **_updateNode**(`k`: Buffer, `value`: Buffer, `keyRemainder`: Nibbles, `stack`: TrieNode[]): *void* -*Defined in [baseTrie.ts:299](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L299)* +*Defined in [baseTrie.ts:281](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L281)* Updates a node @@ -269,39 +257,45 @@ Updates a node **Parameters:** -Name | Type | ------- | ------ | -`k` | Buffer | -`value` | Buffer | -`keyRemainder` | number[] | -`stack` | TrieNode[] | +Name | Type | Description | +------ | ------ | ------ | +`k` | Buffer | - | +`value` | Buffer | - | +`keyRemainder` | Nibbles | - | +`stack` | TrieNode[] | | -**Returns:** *Promise‹void›* +**Returns:** *void* ___ -### _walkTrie +### `Private` _walkTrie + +▸ **_walkTrie**(`root`: Buffer, `targetKey?`: Nibbles): *FoundNode[]* + +*Defined in [baseTrie.ts:383](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L383)* -▸ **_walkTrie**(`root`: Buffer, `onNode`: FoundNode): *Promise‹void›* +Walks a trie until finished. -*Defined in [baseTrie.ts:399](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L399)* +**`method`** _walkTrie **Parameters:** Name | Type | ------ | ------ | `root` | Buffer | -`onNode` | FoundNode | +`targetKey?` | Nibbles | -**Returns:** *Promise‹void›* +**Returns:** *FoundNode[]* + +- An array of nodes found ___ ### batch -▸ **batch**(`ops`: BatchDBOp[]): *Promise‹void›* +▸ **batch**(`ops`: BatchDBOp[]): *void* -*Defined in [baseTrie.ts:713](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L713)* +*Defined in [baseTrie.ts:655](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L655)* The given hash of operations (key additions or deletions) are executed on the DB @@ -317,23 +311,23 @@ const ops = [ , { type: 'put', key: Buffer.from('spouse'), value: Buffer.from('Kim Young-sook') } , { type: 'put', key: Buffer.from('occupation'), value: Buffer.from('Clown') } ] -await trie.batch(ops) +trie.batch(ops) **Parameters:** -Name | Type | ------- | ------ | -`ops` | BatchDBOp[] | +Name | Type | Description | +------ | ------ | ------ | +`ops` | BatchDBOp[] | | -**Returns:** *Promise‹void›* +**Returns:** *void* ___ ### checkRoot -▸ **checkRoot**(`root`: Buffer): *Promise‹boolean›* +▸ **checkRoot**(`root`: Buffer): *boolean* -*Defined in [baseTrie.ts:729](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L729)* +*Defined in [baseTrie.ts:671](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L671)* Checks if a given root exists. @@ -343,7 +337,7 @@ Name | Type | ------ | ------ | `root` | Buffer | -**Returns:** *Promise‹boolean›* +**Returns:** *boolean* ___ @@ -351,37 +345,19 @@ ___ ▸ **copy**(): *[Trie](_basetrie_.trie.md)* -*Defined in [baseTrie.ts:692](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L692)* +*Defined in [baseTrie.ts:635](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L635)* **Returns:** *[Trie](_basetrie_.trie.md)* ___ -### createReadStream - -▸ **createReadStream**(): *ReadStream* - -*Defined in [baseTrie.ts:686](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L686)* - -The `data` event is given an `Object` that has two properties; the `key` and the `value`. Both should be Buffers. - -**`method`** createReadStream - -**`memberof`** Trie - -**Returns:** *ReadStream* - -Returns a [stream](https://nodejs.org/dist/latest-v5.x/docs/api/stream.html#stream_class_stream_readable) of the contents of the `trie` - -___ - ### del -▸ **del**(`key`: Buffer): *Promise‹void›* +▸ **del**(`key`: Buffer): *void* -*Defined in [baseTrie.ts:162](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L162)* +*Defined in [baseTrie.ts:166](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L166)* -deletes a value given a `key` +Deletes a value given a `key` **`method`** del @@ -389,19 +365,19 @@ deletes a value given a `key` **Parameters:** -Name | Type | ------- | ------ | -`key` | Buffer | +Name | Type | Description | +------ | ------ | ------ | +`key` | Buffer | | -**Returns:** *Promise‹void›* +**Returns:** *void* ___ ### findPath -▸ **findPath**(`key`: Buffer): *Promise‹Path›* +▸ **findPath**(`key`: Buffer): *Path* -*Defined in [baseTrie.ts:204](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L204)* +*Defined in [baseTrie.ts:205](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L205)* Tries to find a path to the node for the given key. It returns a `stack` of nodes to the closet node. @@ -414,17 +390,17 @@ It returns a `stack` of nodes to the closet node. Name | Type | Description | ------ | ------ | ------ | -`key` | Buffer | the search key | +`key` | Buffer | the search key | -**Returns:** *Promise‹Path›* +**Returns:** *Path* ___ ### get -▸ **get**(`key`: Buffer): *Promise‹Buffer | null›* +▸ **get**(`key`: Buffer): *Buffer | null* -*Defined in [baseTrie.ts:119](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L119)* +*Defined in [baseTrie.ts:127](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L127)* Gets a value given a `key` @@ -438,17 +414,17 @@ Name | Type | Description | ------ | ------ | ------ | `key` | Buffer | the key to search for | -**Returns:** *Promise‹Buffer | null›* +**Returns:** *Buffer | null* -- Returns a promise that resolves to `Buffer` if a value was found or `null` if no value was found. +- Returns `Buffer` if a value was found or `null` if no value was found. ___ ### put -▸ **put**(`key`: Buffer, `value`: Buffer): *Promise‹void›* +▸ **put**(`key`: Buffer, `value`: Buffer): *void* -*Defined in [baseTrie.ts:136](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L136)* +*Defined in [baseTrie.ts:143](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L143)* Stores a given `value` at the given `key` @@ -458,12 +434,12 @@ Stores a given `value` at the given `key` **Parameters:** -Name | Type | ------- | ------ | -`key` | Buffer | -`value` | Buffer | +Name | Type | Description | +------ | ------ | ------ | +`key` | Buffer | - | +`value` | Buffer | | -**Returns:** *Promise‹void›* +**Returns:** *void* ___ @@ -471,7 +447,7 @@ ___ ▸ **setRoot**(`value?`: Buffer): *void* -*Defined in [baseTrie.ts:104](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L104)* +*Defined in [baseTrie.ts:112](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L112)* **Parameters:** @@ -485,9 +461,9 @@ ___ ### `Static` fromProof -▸ **fromProof**(`proofNodes`: Buffer[], `proofTrie?`: [Trie](_basetrie_.trie.md)): *Promise‹[Trie](_basetrie_.trie.md)›* +▸ **fromProof**(`proofNodes`: Buffer[], `proofTrie?`: [Trie](_basetrie_.trie.md)): *[Trie](_basetrie_.trie.md)* -*Defined in [baseTrie.ts:54](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L54)* +*Defined in [baseTrie.ts:65](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L65)* **Parameters:** @@ -496,15 +472,15 @@ Name | Type | `proofNodes` | Buffer[] | `proofTrie?` | [Trie](_basetrie_.trie.md) | -**Returns:** *Promise‹[Trie](_basetrie_.trie.md)›* +**Returns:** *[Trie](_basetrie_.trie.md)* ___ ### `Static` prove -▸ **prove**(`trie`: [Trie](_basetrie_.trie.md), `key`: Buffer): *Promise‹Buffer[]›* +▸ **prove**(`trie`: [Trie](_basetrie_.trie.md), `key`: Buffer): *Buffer[]* -*Defined in [baseTrie.ts:74](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L74)* +*Defined in [baseTrie.ts:86](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L86)* **Parameters:** @@ -513,15 +489,15 @@ Name | Type | `trie` | [Trie](_basetrie_.trie.md) | `key` | Buffer | -**Returns:** *Promise‹Buffer[]›* +**Returns:** *Buffer[]* ___ ### `Static` verifyProof -▸ **verifyProof**(`rootHash`: Buffer, `key`: Buffer, `proofNodes`: Buffer[]): *Promise‹Buffer | null›* +▸ **verifyProof**(`rootHash`: Buffer, `key`: Buffer, `proofNodes`: Buffer[]): *Buffer | null* -*Defined in [baseTrie.ts:82](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L82)* +*Defined in [baseTrie.ts:94](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L94)* **Parameters:** @@ -531,4 +507,4 @@ Name | Type | `key` | Buffer | `proofNodes` | Buffer[] | -**Returns:** *Promise‹Buffer | null›* +**Returns:** *Buffer | null* diff --git a/docs/classes/_checkpointtrie_.checkpointtrie.md b/docs/classes/_checkpointtrie_.checkpointtrie.md index c2532c7..afdf457 100644 --- a/docs/classes/_checkpointtrie_.checkpointtrie.md +++ b/docs/classes/_checkpointtrie_.checkpointtrie.md @@ -31,25 +31,23 @@ ### Methods +* [_commitChanges](_checkpointtrie_.checkpointtrie.md#private-_commitchanges) * [_createInitialNode](_checkpointtrie_.checkpointtrie.md#_createinitialnode) -* [_createScratchReadStream](_checkpointtrie_.checkpointtrie.md#private-_createscratchreadstream) * [_deleteNode](_checkpointtrie_.checkpointtrie.md#_deletenode) * [_enterCpMode](_checkpointtrie_.checkpointtrie.md#private-_entercpmode) * [_exitCpMode](_checkpointtrie_.checkpointtrie.md#private-_exitcpmode) * [_findDbNodes](_checkpointtrie_.checkpointtrie.md#_finddbnodes) -* [_findValueNodes](_checkpointtrie_.checkpointtrie.md#_findvaluenodes) -* [_formatNode](_checkpointtrie_.checkpointtrie.md#_formatnode) +* [_formatNode](_checkpointtrie_.checkpointtrie.md#private-_formatnode) * [_lookupNode](_checkpointtrie_.checkpointtrie.md#_lookupnode) * [_putNode](_checkpointtrie_.checkpointtrie.md#_putnode) * [_saveStack](_checkpointtrie_.checkpointtrie.md#private-_savestack) * [_updateNode](_checkpointtrie_.checkpointtrie.md#private-_updatenode) -* [_walkTrie](_checkpointtrie_.checkpointtrie.md#_walktrie) +* [_walkTrie](_checkpointtrie_.checkpointtrie.md#private-_walktrie) * [batch](_checkpointtrie_.checkpointtrie.md#batch) * [checkRoot](_checkpointtrie_.checkpointtrie.md#checkroot) * [checkpoint](_checkpointtrie_.checkpointtrie.md#checkpoint) * [commit](_checkpointtrie_.checkpointtrie.md#commit) * [copy](_checkpointtrie_.checkpointtrie.md#copy) -* [createReadStream](_checkpointtrie_.checkpointtrie.md#createreadstream) * [del](_checkpointtrie_.checkpointtrie.md#del) * [findPath](_checkpointtrie_.checkpointtrie.md#findpath) * [get](_checkpointtrie_.checkpointtrie.md#get) @@ -68,7 +66,7 @@ *Overrides [Trie](_basetrie_.trie.md).[constructor](_basetrie_.trie.md#constructor)* -*Defined in [checkpointTrie.ts:11](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L11)* +*Defined in [checkpointTrie.ts:9](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L9)* **Parameters:** @@ -86,7 +84,7 @@ Name | Type | *Inherited from [Trie](_basetrie_.trie.md).[EMPTY_TRIE_ROOT](_basetrie_.trie.md#empty_trie_root)* -*Defined in [baseTrie.ts:39](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L39)* +*Defined in [baseTrie.ts:41](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L41)* ___ @@ -94,7 +92,7 @@ ___ • **_checkpoints**: *Buffer[]* -*Defined in [checkpointTrie.ts:11](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L11)* +*Defined in [checkpointTrie.ts:9](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L9)* ___ @@ -102,7 +100,7 @@ ___ • **_mainDB**: *DB* -*Defined in [checkpointTrie.ts:9](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L9)* +*Defined in [checkpointTrie.ts:7](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L7)* ___ @@ -110,7 +108,7 @@ ___ • **_scratch**: *ScratchDB | null* -*Defined in [checkpointTrie.ts:10](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L10)* +*Defined in [checkpointTrie.ts:8](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L8)* ___ @@ -120,7 +118,7 @@ ___ *Inherited from [Trie](_basetrie_.trie.md).[db](_basetrie_.trie.md#db)* -*Defined in [baseTrie.ts:40](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L40)* +*Defined in [baseTrie.ts:42](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L42)* ## Accessors @@ -128,7 +126,7 @@ ___ • **get isCheckpoint**(): *boolean* -*Defined in [checkpointTrie.ts:26](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L26)* +*Defined in [checkpointTrie.ts:24](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L24)* Is the trie during a checkpoint phase? @@ -142,7 +140,7 @@ ___ *Inherited from [Trie](_basetrie_.trie.md).[root](_basetrie_.trie.md#root)* -*Defined in [baseTrie.ts:100](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L100)* +*Defined in [baseTrie.ts:108](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L108)* **Returns:** *Buffer* @@ -150,7 +148,7 @@ ___ *Inherited from [Trie](_basetrie_.trie.md).[root](_basetrie_.trie.md#root)* -*Defined in [baseTrie.ts:96](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L96)* +*Defined in [baseTrie.ts:104](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L104)* **Parameters:** @@ -162,53 +160,54 @@ Name | Type | ## Methods -### _createInitialNode +### `Private` _commitChanges -▸ **_createInitialNode**(`key`: Buffer, `value`: Buffer): *Promise‹void›* +▸ **_commitChanges**(`scratchDb?`: ScratchDB): *void* -*Inherited from [Trie](_basetrie_.trie.md).[_createInitialNode](_basetrie_.trie.md#_createinitialnode)* +*Defined in [checkpointTrie.ts:121](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L121)* -*Defined in [baseTrie.ts:651](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L651)* +Commits changes based on the state updates since checkpoint. + +**`method`** _commitChanges **Parameters:** Name | Type | ------ | ------ | -`key` | Buffer | -`value` | Buffer | +`scratchDb?` | ScratchDB | -**Returns:** *Promise‹void›* +**Returns:** *void* ___ -### `Private` _createScratchReadStream +### _createInitialNode -▸ **_createScratchReadStream**(`scratchDb?`: ScratchDB): *ScratchReadStream‹›* +▸ **_createInitialNode**(`key`: Buffer, `value`: Buffer): *void* -*Defined in [checkpointTrie.ts:137](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L137)* +*Inherited from [Trie](_basetrie_.trie.md).[_createInitialNode](_basetrie_.trie.md#_createinitialnode)* -Returns a `ScratchReadStream` based on the state updates -since checkpoint. +*Defined in [baseTrie.ts:596](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L596)* -**`method`** createScratchReadStream +Creates the initial node from an empty tree **Parameters:** Name | Type | ------ | ------ | -`scratchDb?` | ScratchDB | +`key` | Buffer | +`value` | Buffer | -**Returns:** *ScratchReadStream‹›* +**Returns:** *void* ___ ### _deleteNode -▸ **_deleteNode**(`k`: Buffer, `stack`: TrieNode[]): *Promise‹void›* +▸ **_deleteNode**(`k`: Buffer, `stack`: TrieNode[]): *void* *Inherited from [Trie](_basetrie_.trie.md).[_deleteNode](_basetrie_.trie.md#_deletenode)* -*Defined in [baseTrie.ts:529](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L529)* +*Defined in [baseTrie.ts:474](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L474)* **Parameters:** @@ -217,7 +216,7 @@ Name | Type | `k` | Buffer | `stack` | TrieNode[] | -**Returns:** *Promise‹void›* +**Returns:** *void* ___ @@ -225,7 +224,7 @@ ___ ▸ **_enterCpMode**(): *void* -*Defined in [checkpointTrie.ts:106](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L106)* +*Defined in [checkpointTrie.ts:96](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L96)* Enter into checkpoint mode. @@ -235,9 +234,9 @@ ___ ### `Private` _exitCpMode -▸ **_exitCpMode**(`commitState`: boolean): *Promise‹void›* +▸ **_exitCpMode**(`commitState`: boolean): *void* -*Defined in [checkpointTrie.ts:115](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L115)* +*Defined in [checkpointTrie.ts:105](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L105)* Exit from checkpoint mode. @@ -247,74 +246,58 @@ Name | Type | ------ | ------ | `commitState` | boolean | -**Returns:** *Promise‹void›* +**Returns:** *void* ___ ### _findDbNodes -▸ **_findDbNodes**(`onFound`: FoundNode): *Promise‹void›* +▸ **_findDbNodes**(): *FoundNode[]* *Inherited from [Trie](_basetrie_.trie.md).[_findDbNodes](_basetrie_.trie.md#_finddbnodes)* -*Defined in [baseTrie.ts:279](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L279)* - -**Parameters:** +*Defined in [baseTrie.ts:258](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L258)* -Name | Type | ------- | ------ | -`onFound` | FoundNode | - -**Returns:** *Promise‹void›* +**Returns:** *FoundNode[]* ___ -### _findValueNodes - -▸ **_findValueNodes**(`onFound`: FoundNode): *Promise‹void›* - -*Inherited from [Trie](_basetrie_.trie.md).[_findValueNodes](_basetrie_.trie.md#_findvaluenodes)* - -*Defined in [baseTrie.ts:257](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L257)* - -**Parameters:** +### `Private` _formatNode -Name | Type | ------- | ------ | -`onFound` | FoundNode | - -**Returns:** *Promise‹void›* - -___ +▸ **_formatNode**(`node`: TrieNode, `topLevel`: boolean, `opStack`: BatchDBOp[], `remove`: boolean): *Buffer‹› | null | Buffer‹› | Buffer‹›[][]* -### _formatNode +*Overrides [Trie](_basetrie_.trie.md).[_formatNode](_basetrie_.trie.md#private-_formatnode)* -▸ **_formatNode**(`node`: TrieNode, `topLevel`: boolean, `opStack`: BatchDBOp[], `remove`: boolean): *Buffer‹› | null | Buffer‹› | Buffer‹›[][]* +*Defined in [checkpointTrie.ts:153](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L153)* -*Overrides [Trie](_basetrie_.trie.md).[_formatNode](_basetrie_.trie.md#_formatnode)* +Formats node to be saved by db.batch. -*Defined in [checkpointTrie.ts:149](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L149)* +**`method`** _formatNode **Parameters:** -Name | Type | Default | ------- | ------ | ------ | -`node` | TrieNode | - | -`topLevel` | boolean | - | -`opStack` | BatchDBOp[] | - | -`remove` | boolean | false | +Name | Type | Default | Description | +------ | ------ | ------ | ------ | +`node` | TrieNode | - | the node to format | +`topLevel` | boolean | - | if the node is at the top level | +`opStack` | BatchDBOp[] | - | the opStack to push the node's data | +`remove` | boolean | false | whether to remove the node (only used for CheckpointTrie) | **Returns:** *Buffer‹› | null | Buffer‹› | Buffer‹›[][]* +- the node's hash used as the key or the rawNode + ___ ### _lookupNode -▸ **_lookupNode**(`node`: Buffer | Buffer[]): *Promise‹TrieNode | null›* +▸ **_lookupNode**(`node`: Buffer | Buffer[]): *TrieNode | null* *Inherited from [Trie](_basetrie_.trie.md).[_lookupNode](_basetrie_.trie.md#_lookupnode)* -*Defined in [baseTrie.ts:172](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L172)* +*Defined in [baseTrie.ts:174](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L174)* + +Retrieves a node from db by hash **Parameters:** @@ -322,17 +305,19 @@ Name | Type | ------ | ------ | `node` | Buffer | Buffer[] | -**Returns:** *Promise‹TrieNode | null›* +**Returns:** *TrieNode | null* ___ ### _putNode -▸ **_putNode**(`node`: TrieNode): *Promise‹void›* +▸ **_putNode**(`node`: TrieNode): *void* *Inherited from [Trie](_basetrie_.trie.md).[_putNode](_basetrie_.trie.md#_putnode)* -*Defined in [baseTrie.ts:190](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L190)* +*Defined in [baseTrie.ts:192](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L192)* + +Writes a single node to db **Parameters:** @@ -340,17 +325,17 @@ Name | Type | ------ | ------ | `node` | TrieNode | -**Returns:** *Promise‹void›* +**Returns:** *void* ___ ### `Private` _saveStack -▸ **_saveStack**(`key`: number[], `stack`: TrieNode[], `opStack`: BatchDBOp[]): *Promise‹void›* +▸ **_saveStack**(`key`: Nibbles, `stack`: TrieNode[], `opStack`: BatchDBOp[]): *void* *Inherited from [Trie](_basetrie_.trie.md).[_saveStack](_basetrie_.trie.md#private-_savestack)* -*Defined in [baseTrie.ts:500](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L500)* +*Defined in [baseTrie.ts:445](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L445)* saves a stack @@ -360,21 +345,21 @@ saves a stack Name | Type | Description | ------ | ------ | ------ | -`key` | number[] | the key. Should follow the stack | +`key` | Nibbles | the key. Should follow the stack | `stack` | TrieNode[] | a stack of nodes to the value given by the key | -`opStack` | BatchDBOp[] | a stack of levelup operations to commit at the end of this funciton | +`opStack` | BatchDBOp[] | a stack of levelup operations to commit at the end of this funciton | -**Returns:** *Promise‹void›* +**Returns:** *void* ___ ### `Private` _updateNode -▸ **_updateNode**(`k`: Buffer, `value`: Buffer, `keyRemainder`: number[], `stack`: TrieNode[]): *Promise‹void›* +▸ **_updateNode**(`k`: Buffer, `value`: Buffer, `keyRemainder`: Nibbles, `stack`: TrieNode[]): *void* *Inherited from [Trie](_basetrie_.trie.md).[_updateNode](_basetrie_.trie.md#private-_updatenode)* -*Defined in [baseTrie.ts:299](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L299)* +*Defined in [baseTrie.ts:281](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L281)* Updates a node @@ -382,43 +367,49 @@ Updates a node **Parameters:** -Name | Type | ------- | ------ | -`k` | Buffer | -`value` | Buffer | -`keyRemainder` | number[] | -`stack` | TrieNode[] | +Name | Type | Description | +------ | ------ | ------ | +`k` | Buffer | - | +`value` | Buffer | - | +`keyRemainder` | Nibbles | - | +`stack` | TrieNode[] | | -**Returns:** *Promise‹void›* +**Returns:** *void* ___ -### _walkTrie +### `Private` _walkTrie + +▸ **_walkTrie**(`root`: Buffer, `targetKey?`: Nibbles): *FoundNode[]* + +*Inherited from [Trie](_basetrie_.trie.md).[_walkTrie](_basetrie_.trie.md#private-_walktrie)* -▸ **_walkTrie**(`root`: Buffer, `onNode`: FoundNode): *Promise‹void›* +*Defined in [baseTrie.ts:383](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L383)* -*Inherited from [Trie](_basetrie_.trie.md).[_walkTrie](_basetrie_.trie.md#_walktrie)* +Walks a trie until finished. -*Defined in [baseTrie.ts:399](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L399)* +**`method`** _walkTrie **Parameters:** Name | Type | ------ | ------ | `root` | Buffer | -`onNode` | FoundNode | +`targetKey?` | Nibbles | -**Returns:** *Promise‹void›* +**Returns:** *FoundNode[]* + +- An array of nodes found ___ ### batch -▸ **batch**(`ops`: BatchDBOp[]): *Promise‹void›* +▸ **batch**(`ops`: BatchDBOp[]): *void* *Inherited from [Trie](_basetrie_.trie.md).[batch](_basetrie_.trie.md#batch)* -*Defined in [baseTrie.ts:713](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L713)* +*Defined in [baseTrie.ts:655](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L655)* The given hash of operations (key additions or deletions) are executed on the DB @@ -434,25 +425,25 @@ const ops = [ , { type: 'put', key: Buffer.from('spouse'), value: Buffer.from('Kim Young-sook') } , { type: 'put', key: Buffer.from('occupation'), value: Buffer.from('Clown') } ] -await trie.batch(ops) +trie.batch(ops) **Parameters:** -Name | Type | ------- | ------ | -`ops` | BatchDBOp[] | +Name | Type | Description | +------ | ------ | ------ | +`ops` | BatchDBOp[] | | -**Returns:** *Promise‹void›* +**Returns:** *void* ___ ### checkRoot -▸ **checkRoot**(`root`: Buffer): *Promise‹boolean›* +▸ **checkRoot**(`root`: Buffer): *boolean* *Inherited from [Trie](_basetrie_.trie.md).[checkRoot](_basetrie_.trie.md#checkroot)* -*Defined in [baseTrie.ts:729](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L729)* +*Defined in [baseTrie.ts:671](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L671)* Checks if a given root exists. @@ -462,7 +453,7 @@ Name | Type | ------ | ------ | `root` | Buffer | -**Returns:** *Promise‹boolean›* +**Returns:** *boolean* ___ @@ -470,12 +461,11 @@ ___ ▸ **checkpoint**(): *void* -*Defined in [checkpointTrie.ts:36](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L36)* +*Defined in [checkpointTrie.ts:33](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L33)* Creates a checkpoint that can later be reverted to or committed. After this is called, no changes to the trie will be permanently saved -until `commit` is called. Calling `putRaw` overrides the checkpointing -mechanism and would directly write to db. +until `commit` is called. **Returns:** *void* @@ -483,9 +473,9 @@ ___ ### commit -▸ **commit**(): *Promise‹void›* +▸ **commit**(): *void* -*Defined in [checkpointTrie.ts:53](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L53)* +*Defined in [checkpointTrie.ts:49](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L49)* Commits a checkpoint to disk, if current checkpoint is not nested. If nested, only sets the parent checkpoint as current checkpoint. @@ -494,7 +484,7 @@ nested, only sets the parent checkpoint as current checkpoint. **`throws`** If not during a checkpoint phase -**Returns:** *Promise‹void›* +**Returns:** *void* ___ @@ -504,7 +494,7 @@ ___ *Overrides [Trie](_basetrie_.trie.md).[copy](_basetrie_.trie.md#copy)* -*Defined in [checkpointTrie.ts:91](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L91)* +*Defined in [checkpointTrie.ts:81](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L81)* Returns a copy of the underlying trie with the interface of CheckpointTrie. If during a checkpoint, the copy will @@ -520,35 +510,15 @@ Name | Type | Default | Description | ___ -### createReadStream - -▸ **createReadStream**(): *ReadStream* - -*Inherited from [Trie](_basetrie_.trie.md).[createReadStream](_basetrie_.trie.md#createreadstream)* - -*Defined in [baseTrie.ts:686](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L686)* - -The `data` event is given an `Object` that has two properties; the `key` and the `value`. Both should be Buffers. - -**`method`** createReadStream - -**`memberof`** Trie - -**Returns:** *ReadStream* - -Returns a [stream](https://nodejs.org/dist/latest-v5.x/docs/api/stream.html#stream_class_stream_readable) of the contents of the `trie` - -___ - ### del -▸ **del**(`key`: Buffer): *Promise‹void›* +▸ **del**(`key`: Buffer): *void* *Inherited from [Trie](_basetrie_.trie.md).[del](_basetrie_.trie.md#del)* -*Defined in [baseTrie.ts:162](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L162)* +*Defined in [baseTrie.ts:166](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L166)* -deletes a value given a `key` +Deletes a value given a `key` **`method`** del @@ -556,21 +526,21 @@ deletes a value given a `key` **Parameters:** -Name | Type | ------- | ------ | -`key` | Buffer | +Name | Type | Description | +------ | ------ | ------ | +`key` | Buffer | | -**Returns:** *Promise‹void›* +**Returns:** *void* ___ ### findPath -▸ **findPath**(`key`: Buffer): *Promise‹Path›* +▸ **findPath**(`key`: Buffer): *Path* *Inherited from [Trie](_basetrie_.trie.md).[findPath](_basetrie_.trie.md#findpath)* -*Defined in [baseTrie.ts:204](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L204)* +*Defined in [baseTrie.ts:205](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L205)* Tries to find a path to the node for the given key. It returns a `stack` of nodes to the closet node. @@ -583,19 +553,19 @@ It returns a `stack` of nodes to the closet node. Name | Type | Description | ------ | ------ | ------ | -`key` | Buffer | the search key | +`key` | Buffer | the search key | -**Returns:** *Promise‹Path›* +**Returns:** *Path* ___ ### get -▸ **get**(`key`: Buffer): *Promise‹Buffer | null›* +▸ **get**(`key`: Buffer): *Buffer | null* *Inherited from [Trie](_basetrie_.trie.md).[get](_basetrie_.trie.md#get)* -*Defined in [baseTrie.ts:119](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L119)* +*Defined in [baseTrie.ts:127](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L127)* Gets a value given a `key` @@ -609,19 +579,19 @@ Name | Type | Description | ------ | ------ | ------ | `key` | Buffer | the key to search for | -**Returns:** *Promise‹Buffer | null›* +**Returns:** *Buffer | null* -- Returns a promise that resolves to `Buffer` if a value was found or `null` if no value was found. +- Returns `Buffer` if a value was found or `null` if no value was found. ___ ### put -▸ **put**(`key`: Buffer, `value`: Buffer): *Promise‹void›* +▸ **put**(`key`: Buffer, `value`: Buffer): *void* *Inherited from [Trie](_basetrie_.trie.md).[put](_basetrie_.trie.md#put)* -*Defined in [baseTrie.ts:136](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L136)* +*Defined in [baseTrie.ts:143](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L143)* Stores a given `value` at the given `key` @@ -631,26 +601,26 @@ Stores a given `value` at the given `key` **Parameters:** -Name | Type | ------- | ------ | -`key` | Buffer | -`value` | Buffer | +Name | Type | Description | +------ | ------ | ------ | +`key` | Buffer | - | +`value` | Buffer | | -**Returns:** *Promise‹void›* +**Returns:** *void* ___ ### revert -▸ **revert**(): *Promise‹void›* +▸ **revert**(): *void* -*Defined in [checkpointTrie.ts:73](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L73)* +*Defined in [checkpointTrie.ts:65](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L65)* Reverts the trie to the state it was at when `checkpoint` was first called. If during a nested checkpoint, sets root to most recent checkpoint, and sets parent checkpoint as current. -**Returns:** *Promise‹void›* +**Returns:** *void* ___ @@ -660,7 +630,7 @@ ___ *Inherited from [Trie](_basetrie_.trie.md).[setRoot](_basetrie_.trie.md#setroot)* -*Defined in [baseTrie.ts:104](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L104)* +*Defined in [baseTrie.ts:112](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L112)* **Parameters:** @@ -674,11 +644,11 @@ ___ ### `Static` fromProof -▸ **fromProof**(`proofNodes`: Buffer[], `proofTrie?`: [Trie](_basetrie_.trie.md)): *Promise‹[Trie](_basetrie_.trie.md)›* +▸ **fromProof**(`proofNodes`: Buffer[], `proofTrie?`: [Trie](_basetrie_.trie.md)): *[Trie](_basetrie_.trie.md)* *Inherited from [Trie](_basetrie_.trie.md).[fromProof](_basetrie_.trie.md#static-fromproof)* -*Defined in [baseTrie.ts:54](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L54)* +*Defined in [baseTrie.ts:65](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L65)* **Parameters:** @@ -687,17 +657,17 @@ Name | Type | `proofNodes` | Buffer[] | `proofTrie?` | [Trie](_basetrie_.trie.md) | -**Returns:** *Promise‹[Trie](_basetrie_.trie.md)›* +**Returns:** *[Trie](_basetrie_.trie.md)* ___ ### `Static` prove -▸ **prove**(`trie`: [Trie](_basetrie_.trie.md), `key`: Buffer): *Promise‹Buffer[]›* +▸ **prove**(`trie`: [Trie](_basetrie_.trie.md), `key`: Buffer): *Buffer[]* *Inherited from [Trie](_basetrie_.trie.md).[prove](_basetrie_.trie.md#static-prove)* -*Defined in [baseTrie.ts:74](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L74)* +*Defined in [baseTrie.ts:86](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L86)* **Parameters:** @@ -706,17 +676,17 @@ Name | Type | `trie` | [Trie](_basetrie_.trie.md) | `key` | Buffer | -**Returns:** *Promise‹Buffer[]›* +**Returns:** *Buffer[]* ___ ### `Static` verifyProof -▸ **verifyProof**(`rootHash`: Buffer, `key`: Buffer, `proofNodes`: Buffer[]): *Promise‹Buffer | null›* +▸ **verifyProof**(`rootHash`: Buffer, `key`: Buffer, `proofNodes`: Buffer[]): *Buffer | null* *Inherited from [Trie](_basetrie_.trie.md).[verifyProof](_basetrie_.trie.md#static-verifyproof)* -*Defined in [baseTrie.ts:82](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L82)* +*Defined in [baseTrie.ts:94](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L94)* **Parameters:** @@ -726,4 +696,4 @@ Name | Type | `key` | Buffer | `proofNodes` | Buffer[] | -**Returns:** *Promise‹Buffer | null›* +**Returns:** *Buffer | null* diff --git a/docs/classes/_secure_.securetrie.md b/docs/classes/_secure_.securetrie.md index 4a61cdf..27998a4 100644 --- a/docs/classes/_secure_.securetrie.md +++ b/docs/classes/_secure_.securetrie.md @@ -37,25 +37,23 @@ It has the same methods and constructor as `Trie`. ### Methods +* [_commitChanges](_secure_.securetrie.md#private-_commitchanges) * [_createInitialNode](_secure_.securetrie.md#_createinitialnode) -* [_createScratchReadStream](_secure_.securetrie.md#private-_createscratchreadstream) * [_deleteNode](_secure_.securetrie.md#_deletenode) * [_enterCpMode](_secure_.securetrie.md#private-_entercpmode) * [_exitCpMode](_secure_.securetrie.md#private-_exitcpmode) * [_findDbNodes](_secure_.securetrie.md#_finddbnodes) -* [_findValueNodes](_secure_.securetrie.md#_findvaluenodes) -* [_formatNode](_secure_.securetrie.md#_formatnode) +* [_formatNode](_secure_.securetrie.md#private-_formatnode) * [_lookupNode](_secure_.securetrie.md#_lookupnode) * [_putNode](_secure_.securetrie.md#_putnode) * [_saveStack](_secure_.securetrie.md#private-_savestack) * [_updateNode](_secure_.securetrie.md#private-_updatenode) -* [_walkTrie](_secure_.securetrie.md#_walktrie) +* [_walkTrie](_secure_.securetrie.md#private-_walktrie) * [batch](_secure_.securetrie.md#batch) * [checkRoot](_secure_.securetrie.md#checkroot) * [checkpoint](_secure_.securetrie.md#checkpoint) * [commit](_secure_.securetrie.md#commit) * [copy](_secure_.securetrie.md#copy) -* [createReadStream](_secure_.securetrie.md#createreadstream) * [del](_secure_.securetrie.md#del) * [findPath](_secure_.securetrie.md#findpath) * [get](_secure_.securetrie.md#get) @@ -92,7 +90,7 @@ Name | Type | *Inherited from [Trie](_basetrie_.trie.md).[EMPTY_TRIE_ROOT](_basetrie_.trie.md#empty_trie_root)* -*Defined in [baseTrie.ts:39](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L39)* +*Defined in [baseTrie.ts:41](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L41)* ___ @@ -102,7 +100,7 @@ ___ *Inherited from [CheckpointTrie](_checkpointtrie_.checkpointtrie.md).[_checkpoints](_checkpointtrie_.checkpointtrie.md#_checkpoints)* -*Defined in [checkpointTrie.ts:11](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L11)* +*Defined in [checkpointTrie.ts:9](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L9)* ___ @@ -112,7 +110,7 @@ ___ *Inherited from [CheckpointTrie](_checkpointtrie_.checkpointtrie.md).[_mainDB](_checkpointtrie_.checkpointtrie.md#_maindb)* -*Defined in [checkpointTrie.ts:9](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L9)* +*Defined in [checkpointTrie.ts:7](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L7)* ___ @@ -122,7 +120,7 @@ ___ *Inherited from [CheckpointTrie](_checkpointtrie_.checkpointtrie.md).[_scratch](_checkpointtrie_.checkpointtrie.md#_scratch)* -*Defined in [checkpointTrie.ts:10](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L10)* +*Defined in [checkpointTrie.ts:8](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L8)* ___ @@ -132,7 +130,7 @@ ___ *Inherited from [Trie](_basetrie_.trie.md).[db](_basetrie_.trie.md#db)* -*Defined in [baseTrie.ts:40](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L40)* +*Defined in [baseTrie.ts:42](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L42)* ## Accessors @@ -142,7 +140,7 @@ ___ *Inherited from [CheckpointTrie](_checkpointtrie_.checkpointtrie.md).[isCheckpoint](_checkpointtrie_.checkpointtrie.md#ischeckpoint)* -*Defined in [checkpointTrie.ts:26](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L26)* +*Defined in [checkpointTrie.ts:24](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L24)* Is the trie during a checkpoint phase? @@ -156,7 +154,7 @@ ___ *Inherited from [Trie](_basetrie_.trie.md).[root](_basetrie_.trie.md#root)* -*Defined in [baseTrie.ts:100](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L100)* +*Defined in [baseTrie.ts:108](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L108)* **Returns:** *Buffer* @@ -164,7 +162,7 @@ ___ *Inherited from [Trie](_basetrie_.trie.md).[root](_basetrie_.trie.md#root)* -*Defined in [baseTrie.ts:96](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L96)* +*Defined in [baseTrie.ts:104](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L104)* **Parameters:** @@ -176,55 +174,56 @@ Name | Type | ## Methods -### _createInitialNode +### `Private` _commitChanges -▸ **_createInitialNode**(`key`: Buffer, `value`: Buffer): *Promise‹void›* +▸ **_commitChanges**(`scratchDb?`: ScratchDB): *void* -*Inherited from [Trie](_basetrie_.trie.md).[_createInitialNode](_basetrie_.trie.md#_createinitialnode)* +*Inherited from [CheckpointTrie](_checkpointtrie_.checkpointtrie.md).[_commitChanges](_checkpointtrie_.checkpointtrie.md#private-_commitchanges)* -*Defined in [baseTrie.ts:651](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L651)* +*Defined in [checkpointTrie.ts:121](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L121)* + +Commits changes based on the state updates since checkpoint. + +**`method`** _commitChanges **Parameters:** Name | Type | ------ | ------ | -`key` | Buffer | -`value` | Buffer | +`scratchDb?` | ScratchDB | -**Returns:** *Promise‹void›* +**Returns:** *void* ___ -### `Private` _createScratchReadStream - -▸ **_createScratchReadStream**(`scratchDb?`: ScratchDB): *ScratchReadStream‹›* +### _createInitialNode -*Inherited from [CheckpointTrie](_checkpointtrie_.checkpointtrie.md).[_createScratchReadStream](_checkpointtrie_.checkpointtrie.md#private-_createscratchreadstream)* +▸ **_createInitialNode**(`key`: Buffer, `value`: Buffer): *void* -*Defined in [checkpointTrie.ts:137](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L137)* +*Inherited from [Trie](_basetrie_.trie.md).[_createInitialNode](_basetrie_.trie.md#_createinitialnode)* -Returns a `ScratchReadStream` based on the state updates -since checkpoint. +*Defined in [baseTrie.ts:596](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L596)* -**`method`** createScratchReadStream +Creates the initial node from an empty tree **Parameters:** Name | Type | ------ | ------ | -`scratchDb?` | ScratchDB | +`key` | Buffer | +`value` | Buffer | -**Returns:** *ScratchReadStream‹›* +**Returns:** *void* ___ ### _deleteNode -▸ **_deleteNode**(`k`: Buffer, `stack`: TrieNode[]): *Promise‹void›* +▸ **_deleteNode**(`k`: Buffer, `stack`: TrieNode[]): *void* *Inherited from [Trie](_basetrie_.trie.md).[_deleteNode](_basetrie_.trie.md#_deletenode)* -*Defined in [baseTrie.ts:529](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L529)* +*Defined in [baseTrie.ts:474](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L474)* **Parameters:** @@ -233,7 +232,7 @@ Name | Type | `k` | Buffer | `stack` | TrieNode[] | -**Returns:** *Promise‹void›* +**Returns:** *void* ___ @@ -243,7 +242,7 @@ ___ *Inherited from [CheckpointTrie](_checkpointtrie_.checkpointtrie.md).[_enterCpMode](_checkpointtrie_.checkpointtrie.md#private-_entercpmode)* -*Defined in [checkpointTrie.ts:106](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L106)* +*Defined in [checkpointTrie.ts:96](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L96)* Enter into checkpoint mode. @@ -253,11 +252,11 @@ ___ ### `Private` _exitCpMode -▸ **_exitCpMode**(`commitState`: boolean): *Promise‹void›* +▸ **_exitCpMode**(`commitState`: boolean): *void* *Inherited from [CheckpointTrie](_checkpointtrie_.checkpointtrie.md).[_exitCpMode](_checkpointtrie_.checkpointtrie.md#private-_exitcpmode)* -*Defined in [checkpointTrie.ts:115](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L115)* +*Defined in [checkpointTrie.ts:105](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L105)* Exit from checkpoint mode. @@ -267,76 +266,60 @@ Name | Type | ------ | ------ | `commitState` | boolean | -**Returns:** *Promise‹void›* +**Returns:** *void* ___ ### _findDbNodes -▸ **_findDbNodes**(`onFound`: FoundNode): *Promise‹void›* +▸ **_findDbNodes**(): *FoundNode[]* *Inherited from [Trie](_basetrie_.trie.md).[_findDbNodes](_basetrie_.trie.md#_finddbnodes)* -*Defined in [baseTrie.ts:279](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L279)* +*Defined in [baseTrie.ts:258](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L258)* -**Parameters:** - -Name | Type | ------- | ------ | -`onFound` | FoundNode | - -**Returns:** *Promise‹void›* +**Returns:** *FoundNode[]* ___ -### _findValueNodes - -▸ **_findValueNodes**(`onFound`: FoundNode): *Promise‹void›* - -*Inherited from [Trie](_basetrie_.trie.md).[_findValueNodes](_basetrie_.trie.md#_findvaluenodes)* - -*Defined in [baseTrie.ts:257](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L257)* - -**Parameters:** +### `Private` _formatNode -Name | Type | ------- | ------ | -`onFound` | FoundNode | - -**Returns:** *Promise‹void›* - -___ +▸ **_formatNode**(`node`: TrieNode, `topLevel`: boolean, `opStack`: BatchDBOp[], `remove`: boolean): *Buffer‹› | null | Buffer‹› | Buffer‹›[][]* -### _formatNode +*Inherited from [CheckpointTrie](_checkpointtrie_.checkpointtrie.md).[_formatNode](_checkpointtrie_.checkpointtrie.md#private-_formatnode)* -▸ **_formatNode**(`node`: TrieNode, `topLevel`: boolean, `opStack`: BatchDBOp[], `remove`: boolean): *Buffer‹› | null | Buffer‹› | Buffer‹›[][]* +*Overrides [Trie](_basetrie_.trie.md).[_formatNode](_basetrie_.trie.md#private-_formatnode)* -*Inherited from [CheckpointTrie](_checkpointtrie_.checkpointtrie.md).[_formatNode](_checkpointtrie_.checkpointtrie.md#_formatnode)* +*Defined in [checkpointTrie.ts:153](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L153)* -*Overrides [Trie](_basetrie_.trie.md).[_formatNode](_basetrie_.trie.md#_formatnode)* +Formats node to be saved by db.batch. -*Defined in [checkpointTrie.ts:149](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L149)* +**`method`** _formatNode **Parameters:** -Name | Type | Default | ------- | ------ | ------ | -`node` | TrieNode | - | -`topLevel` | boolean | - | -`opStack` | BatchDBOp[] | - | -`remove` | boolean | false | +Name | Type | Default | Description | +------ | ------ | ------ | ------ | +`node` | TrieNode | - | the node to format | +`topLevel` | boolean | - | if the node is at the top level | +`opStack` | BatchDBOp[] | - | the opStack to push the node's data | +`remove` | boolean | false | whether to remove the node (only used for CheckpointTrie) | **Returns:** *Buffer‹› | null | Buffer‹› | Buffer‹›[][]* +- the node's hash used as the key or the rawNode + ___ ### _lookupNode -▸ **_lookupNode**(`node`: Buffer | Buffer[]): *Promise‹TrieNode | null›* +▸ **_lookupNode**(`node`: Buffer | Buffer[]): *TrieNode | null* *Inherited from [Trie](_basetrie_.trie.md).[_lookupNode](_basetrie_.trie.md#_lookupnode)* -*Defined in [baseTrie.ts:172](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L172)* +*Defined in [baseTrie.ts:174](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L174)* + +Retrieves a node from db by hash **Parameters:** @@ -344,17 +327,19 @@ Name | Type | ------ | ------ | `node` | Buffer | Buffer[] | -**Returns:** *Promise‹TrieNode | null›* +**Returns:** *TrieNode | null* ___ ### _putNode -▸ **_putNode**(`node`: TrieNode): *Promise‹void›* +▸ **_putNode**(`node`: TrieNode): *void* *Inherited from [Trie](_basetrie_.trie.md).[_putNode](_basetrie_.trie.md#_putnode)* -*Defined in [baseTrie.ts:190](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L190)* +*Defined in [baseTrie.ts:192](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L192)* + +Writes a single node to db **Parameters:** @@ -362,17 +347,17 @@ Name | Type | ------ | ------ | `node` | TrieNode | -**Returns:** *Promise‹void›* +**Returns:** *void* ___ ### `Private` _saveStack -▸ **_saveStack**(`key`: number[], `stack`: TrieNode[], `opStack`: BatchDBOp[]): *Promise‹void›* +▸ **_saveStack**(`key`: Nibbles, `stack`: TrieNode[], `opStack`: BatchDBOp[]): *void* *Inherited from [Trie](_basetrie_.trie.md).[_saveStack](_basetrie_.trie.md#private-_savestack)* -*Defined in [baseTrie.ts:500](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L500)* +*Defined in [baseTrie.ts:445](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L445)* saves a stack @@ -382,21 +367,21 @@ saves a stack Name | Type | Description | ------ | ------ | ------ | -`key` | number[] | the key. Should follow the stack | +`key` | Nibbles | the key. Should follow the stack | `stack` | TrieNode[] | a stack of nodes to the value given by the key | -`opStack` | BatchDBOp[] | a stack of levelup operations to commit at the end of this funciton | +`opStack` | BatchDBOp[] | a stack of levelup operations to commit at the end of this funciton | -**Returns:** *Promise‹void›* +**Returns:** *void* ___ ### `Private` _updateNode -▸ **_updateNode**(`k`: Buffer, `value`: Buffer, `keyRemainder`: number[], `stack`: TrieNode[]): *Promise‹void›* +▸ **_updateNode**(`k`: Buffer, `value`: Buffer, `keyRemainder`: Nibbles, `stack`: TrieNode[]): *void* *Inherited from [Trie](_basetrie_.trie.md).[_updateNode](_basetrie_.trie.md#private-_updatenode)* -*Defined in [baseTrie.ts:299](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L299)* +*Defined in [baseTrie.ts:281](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L281)* Updates a node @@ -404,43 +389,49 @@ Updates a node **Parameters:** -Name | Type | ------- | ------ | -`k` | Buffer | -`value` | Buffer | -`keyRemainder` | number[] | -`stack` | TrieNode[] | +Name | Type | Description | +------ | ------ | ------ | +`k` | Buffer | - | +`value` | Buffer | - | +`keyRemainder` | Nibbles | - | +`stack` | TrieNode[] | | -**Returns:** *Promise‹void›* +**Returns:** *void* ___ -### _walkTrie +### `Private` _walkTrie + +▸ **_walkTrie**(`root`: Buffer, `targetKey?`: Nibbles): *FoundNode[]* -▸ **_walkTrie**(`root`: Buffer, `onNode`: FoundNode): *Promise‹void›* +*Inherited from [Trie](_basetrie_.trie.md).[_walkTrie](_basetrie_.trie.md#private-_walktrie)* -*Inherited from [Trie](_basetrie_.trie.md).[_walkTrie](_basetrie_.trie.md#_walktrie)* +*Defined in [baseTrie.ts:383](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L383)* -*Defined in [baseTrie.ts:399](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L399)* +Walks a trie until finished. + +**`method`** _walkTrie **Parameters:** Name | Type | ------ | ------ | `root` | Buffer | -`onNode` | FoundNode | +`targetKey?` | Nibbles | + +**Returns:** *FoundNode[]* -**Returns:** *Promise‹void›* +- An array of nodes found ___ ### batch -▸ **batch**(`ops`: BatchDBOp[]): *Promise‹void›* +▸ **batch**(`ops`: BatchDBOp[]): *void* *Inherited from [Trie](_basetrie_.trie.md).[batch](_basetrie_.trie.md#batch)* -*Defined in [baseTrie.ts:713](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L713)* +*Defined in [baseTrie.ts:655](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L655)* The given hash of operations (key additions or deletions) are executed on the DB @@ -456,25 +447,25 @@ const ops = [ , { type: 'put', key: Buffer.from('spouse'), value: Buffer.from('Kim Young-sook') } , { type: 'put', key: Buffer.from('occupation'), value: Buffer.from('Clown') } ] -await trie.batch(ops) +trie.batch(ops) **Parameters:** -Name | Type | ------- | ------ | -`ops` | BatchDBOp[] | +Name | Type | Description | +------ | ------ | ------ | +`ops` | BatchDBOp[] | | -**Returns:** *Promise‹void›* +**Returns:** *void* ___ ### checkRoot -▸ **checkRoot**(`root`: Buffer): *Promise‹boolean›* +▸ **checkRoot**(`root`: Buffer): *boolean* *Inherited from [Trie](_basetrie_.trie.md).[checkRoot](_basetrie_.trie.md#checkroot)* -*Defined in [baseTrie.ts:729](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L729)* +*Defined in [baseTrie.ts:671](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L671)* Checks if a given root exists. @@ -484,7 +475,7 @@ Name | Type | ------ | ------ | `root` | Buffer | -**Returns:** *Promise‹boolean›* +**Returns:** *boolean* ___ @@ -494,12 +485,11 @@ ___ *Inherited from [CheckpointTrie](_checkpointtrie_.checkpointtrie.md).[checkpoint](_checkpointtrie_.checkpointtrie.md#checkpoint)* -*Defined in [checkpointTrie.ts:36](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L36)* +*Defined in [checkpointTrie.ts:33](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L33)* Creates a checkpoint that can later be reverted to or committed. After this is called, no changes to the trie will be permanently saved -until `commit` is called. Calling `putRaw` overrides the checkpointing -mechanism and would directly write to db. +until `commit` is called. **Returns:** *void* @@ -507,11 +497,11 @@ ___ ### commit -▸ **commit**(): *Promise‹void›* +▸ **commit**(): *void* *Inherited from [CheckpointTrie](_checkpointtrie_.checkpointtrie.md).[commit](_checkpointtrie_.checkpointtrie.md#commit)* -*Defined in [checkpointTrie.ts:53](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L53)* +*Defined in [checkpointTrie.ts:49](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L49)* Commits a checkpoint to disk, if current checkpoint is not nested. If nested, only sets the parent checkpoint as current checkpoint. @@ -520,7 +510,7 @@ nested, only sets the parent checkpoint as current checkpoint. **`throws`** If not during a checkpoint phase -**Returns:** *Promise‹void›* +**Returns:** *void* ___ @@ -536,29 +526,9 @@ ___ ___ -### createReadStream - -▸ **createReadStream**(): *ReadStream* - -*Inherited from [Trie](_basetrie_.trie.md).[createReadStream](_basetrie_.trie.md#createreadstream)* - -*Defined in [baseTrie.ts:686](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L686)* - -The `data` event is given an `Object` that has two properties; the `key` and the `value`. Both should be Buffers. - -**`method`** createReadStream - -**`memberof`** Trie - -**Returns:** *ReadStream* - -Returns a [stream](https://nodejs.org/dist/latest-v5.x/docs/api/stream.html#stream_class_stream_readable) of the contents of the `trie` - -___ - ### del -▸ **del**(`key`: Buffer): *Promise‹void›* +▸ **del**(`key`: Buffer): *void* *Overrides [Trie](_basetrie_.trie.md).[del](_basetrie_.trie.md#del)* @@ -570,17 +540,17 @@ Name | Type | ------ | ------ | `key` | Buffer | -**Returns:** *Promise‹void›* +**Returns:** *void* ___ ### findPath -▸ **findPath**(`key`: Buffer): *Promise‹Path›* +▸ **findPath**(`key`: Buffer): *Path* *Inherited from [Trie](_basetrie_.trie.md).[findPath](_basetrie_.trie.md#findpath)* -*Defined in [baseTrie.ts:204](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L204)* +*Defined in [baseTrie.ts:205](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L205)* Tries to find a path to the node for the given key. It returns a `stack` of nodes to the closet node. @@ -593,15 +563,15 @@ It returns a `stack` of nodes to the closet node. Name | Type | Description | ------ | ------ | ------ | -`key` | Buffer | the search key | +`key` | Buffer | the search key | -**Returns:** *Promise‹Path›* +**Returns:** *Path* ___ ### get -▸ **get**(`key`: Buffer): *Promise‹Buffer | null›* +▸ **get**(`key`: Buffer): *Buffer | null* *Overrides [Trie](_basetrie_.trie.md).[get](_basetrie_.trie.md#get)* @@ -613,13 +583,13 @@ Name | Type | ------ | ------ | `key` | Buffer | -**Returns:** *Promise‹Buffer | null›* +**Returns:** *Buffer | null* ___ ### put -▸ **put**(`key`: Buffer, `val`: Buffer): *Promise‹void›* +▸ **put**(`key`: Buffer, `val`: Buffer): *void* *Overrides [Trie](_basetrie_.trie.md).[put](_basetrie_.trie.md#put)* @@ -635,23 +605,23 @@ Name | Type | `key` | Buffer | `val` | Buffer | -**Returns:** *Promise‹void›* +**Returns:** *void* ___ ### revert -▸ **revert**(): *Promise‹void›* +▸ **revert**(): *void* *Inherited from [CheckpointTrie](_checkpointtrie_.checkpointtrie.md).[revert](_checkpointtrie_.checkpointtrie.md#revert)* -*Defined in [checkpointTrie.ts:73](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L73)* +*Defined in [checkpointTrie.ts:65](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/checkpointTrie.ts#L65)* Reverts the trie to the state it was at when `checkpoint` was first called. If during a nested checkpoint, sets root to most recent checkpoint, and sets parent checkpoint as current. -**Returns:** *Promise‹void›* +**Returns:** *void* ___ @@ -661,7 +631,7 @@ ___ *Inherited from [Trie](_basetrie_.trie.md).[setRoot](_basetrie_.trie.md#setroot)* -*Defined in [baseTrie.ts:104](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L104)* +*Defined in [baseTrie.ts:112](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L112)* **Parameters:** @@ -675,11 +645,11 @@ ___ ### `Static` fromProof -▸ **fromProof**(`proofNodes`: Buffer[], `proofTrie?`: [Trie](_basetrie_.trie.md)): *Promise‹[Trie](_basetrie_.trie.md)›* +▸ **fromProof**(`proofNodes`: Buffer[], `proofTrie?`: [Trie](_basetrie_.trie.md)): *[Trie](_basetrie_.trie.md)* *Inherited from [Trie](_basetrie_.trie.md).[fromProof](_basetrie_.trie.md#static-fromproof)* -*Defined in [baseTrie.ts:54](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L54)* +*Defined in [baseTrie.ts:65](https://github.com/ethereumjs/merkle-patricia-tree/blob/master/src/baseTrie.ts#L65)* **Parameters:** @@ -688,13 +658,13 @@ Name | Type | `proofNodes` | Buffer[] | `proofTrie?` | [Trie](_basetrie_.trie.md) | -**Returns:** *Promise‹[Trie](_basetrie_.trie.md)›* +**Returns:** *[Trie](_basetrie_.trie.md)* ___ ### `Static` prove -▸ **prove**(`trie`: [SecureTrie](_secure_.securetrie.md), `key`: Buffer): *Promise‹Buffer[]›* +▸ **prove**(`trie`: [SecureTrie](_secure_.securetrie.md), `key`: Buffer): *Buffer[]* *Overrides [Trie](_basetrie_.trie.md).[prove](_basetrie_.trie.md#static-prove)* @@ -707,13 +677,13 @@ Name | Type | `trie` | [SecureTrie](_secure_.securetrie.md) | `key` | Buffer | -**Returns:** *Promise‹Buffer[]›* +**Returns:** *Buffer[]* ___ ### `Static` verifyProof -▸ **verifyProof**(`rootHash`: Buffer, `key`: Buffer, `proof`: Buffer[]): *Promise‹Buffer | null›* +▸ **verifyProof**(`rootHash`: Buffer, `key`: Buffer, `proof`: Buffer[]): *Buffer | null* *Overrides [Trie](_basetrie_.trie.md).[verifyProof](_basetrie_.trie.md#static-verifyproof)* @@ -727,4 +697,4 @@ Name | Type | `key` | Buffer | `proof` | Buffer[] | -**Returns:** *Promise‹Buffer | null›* +**Returns:** *Buffer | null* diff --git a/karma.conf.js b/karma.conf.js index d872533..02d9aae 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -12,6 +12,7 @@ module.exports = function (config) { }, }, colors: true, + reporters: ['dots', 'karma-typescript'], browsers: ['FirefoxHeadless', 'ChromeHeadless'], singleRun: true, concurrency: Infinity, diff --git a/package.json b/package.json index 99ce2f2..2c3ae49 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "tsc": "ethereumjs-config-tsc", "test": "npm run test:node && npm run test:browser", "test:browser": "npm run build && karma start karma.conf.js", - "test:node": "npm run build && tape -r ts-node/register test/*.ts | tap-prettify -" + "test:node": "npm run build && tape -r ts-node/register test/*.ts" }, "husky": { "hooks": { @@ -47,36 +47,32 @@ ], "license": "MPL-2.0", "dependencies": { - "ethereumjs-util": "^6.1.0", - "level-mem": "^3.0.1", - "level-ws": "^2.0.0", - "readable-stream": "^3.6.0", - "rlp": "^2.2.3", - "semaphore-async-await": "^1.5.1" + "ethereumjs-util": "^6.2.0", + "levelup": "^4.4.0", + "rlp": "^2.2.4" }, "devDependencies": { "@ethereumjs/config-nyc": "^1.1.1", "@ethereumjs/config-prettier": "^1.1.1", "@ethereumjs/config-tsc": "^1.1.1", "@ethereumjs/config-tslint": "^1.1.1", - "@types/bn.js": "^4.11.5", - "@types/levelup": "^3.1.1", - "@types/tape": "^4.2.34", - "husky": "^4.2.3", - "karma": "^4.4.1", + "@types/bn.js": "^4.11.6", + "@types/levelup": "^4.3.0", + "@types/tape": "^4.13.0", + "husky": "^4.2.5", + "karma": "^5.0.2", "karma-chrome-launcher": "^3.1.0", "karma-firefox-launcher": "^1.3.0", "karma-tap": "^4.2.0", - "karma-typescript": "^5.0.1", - "nyc": "^15.0.0", - "prettier": "^2.0.2", - "tap-prettify": "^0.0.2", + "karma-typescript": "^5.0.2", + "nyc": "^15.0.1", + "prettier": "^2.0.5", "tape": "^4.13.2", - "ts-node": "^8.8.1", + "ts-node": "^8.9.0", "tslint": "^5.18.0", "typedoc": "next", - "typedoc-plugin-markdown": "^2.2.16", - "typescript": "^3.7.5", + "typedoc-plugin-markdown": "^2.2.17", + "typescript": "^3.8.3", "typestrict": "^1.0.2" }, "contributors": [ diff --git a/src/baseTrie.ts b/src/baseTrie.ts index e30bc37..37be537 100644 --- a/src/baseTrie.ts +++ b/src/baseTrie.ts @@ -1,12 +1,10 @@ -import Semaphore from 'semaphore-async-await' import { LevelUp } from 'levelup' import { keccak, KECCAK256_RLP } from 'ethereumjs-util' -import { DB, BatchDBOp, PutBatch } from './db' -import { TrieReadStream as ReadStream } from './readStream' -import { PrioritizedTaskExecutor } from './prioritizedTaskExecutor' +import { DB, DBMap, BatchDBOp, PutBatch } from './db' import { bufferToNibbles, matchingNibbleLength, doKeysMatch } from './util/nibbles' import { TrieNode, + Nibbles, decodeNode, decodeRawNode, isRawNode, @@ -19,18 +17,22 @@ const assert = require('assert') interface Path { node: TrieNode | null - remaining: number[] + remaining: Nibbles stack: TrieNode[] } -type FoundNode = (nodeRef: Buffer, node: TrieNode, key: number[], walkController: any) => void +interface FoundNode { + nodeRef: Buffer + node: TrieNode + key: Nibbles +} /** - * Use `import { BaseTrie as Trie } from 'merkle-patricia-tree'` for the base interface. - * In Ethereum applications stick with the Secure Trie Overlay `import { SecureTrie } from 'merkle-patricia-tree'`. + * Use `import { BaseTrie } from 'merkle-patricia-tree'` for the base interface. + * In Ethereum applications use the Secure Trie Overlay: `import { SecureTrie } from 'merkle-patricia-tree'`. * The API for the base and the secure interface are about the same. - * @param {Object} [db] - A [levelup](https://github.com/Level/levelup) instance. By default creates an in-memory [memdown](https://github.com/Level/memdown) instance. - * If the db is `null` or left undefined, then the trie will be stored in memory via [memdown](https://github.com/Level/memdown) + * @param {LevelUp | DBMap} [db] - You may pass in a [levelup](https://github.com/Level/levelup) instance to get loaded into memory. + * If the db is `null` or left undefined, then the trie will be stored via an in-memory JavaScript map. * @param {Buffer} [root] - A `Buffer` for the root of a previously stored trie * @prop {Buffer} root - The current root of the `trie` * @prop {Buffer} EMPTY_TRIE_ROOT - The root for an empty trie @@ -38,20 +40,29 @@ type FoundNode = (nodeRef: Buffer, node: TrieNode, key: number[], walkController export class Trie { EMPTY_TRIE_ROOT: Buffer db: DB - protected lock: Semaphore private _root: Buffer - constructor(db?: LevelUp | null, root?: Buffer) { + constructor(db?: LevelUp | DBMap | null, root?: Buffer) { this.EMPTY_TRIE_ROOT = KECCAK256_RLP - this.lock = new Semaphore(1) - this.db = db ? new DB(db) : new DB() + + if (db) { + if (db instanceof Map) { + this.db = new DB({ map: db }) + } else { + // db is instanceOf LevelUp + this.db = new DB({ leveldb: db }) + } + } else { + this.db = new DB() + } + this._root = this.EMPTY_TRIE_ROOT if (root) { this.setRoot(root) } } - static async fromProof(proofNodes: Buffer[], proofTrie?: Trie): Promise { + static fromProof(proofNodes: Buffer[], proofTrie?: Trie): Trie { let opStack = proofNodes.map((nodeValue) => { return { type: 'put', @@ -67,26 +78,23 @@ export class Trie { } } - await proofTrie.db.batch(opStack) + proofTrie.db.batch(opStack) + return proofTrie } - static async prove(trie: Trie, key: Buffer): Promise { - const { stack } = await trie.findPath(key) + static prove(trie: Trie, key: Buffer): Buffer[] { + const { stack } = trie.findPath(key) const p = stack.map((stackElem) => { return stackElem.serialize() }) return p } - static async verifyProof( - rootHash: Buffer, - key: Buffer, - proofNodes: Buffer[], - ): Promise { + static verifyProof(rootHash: Buffer, key: Buffer, proofNodes: Buffer[]): Buffer | null { let proofTrie = new Trie(null, rootHash) try { - proofTrie = await Trie.fromProof(proofNodes, proofTrie) + proofTrie = Trie.fromProof(proofNodes, proofTrie) } catch (e) { throw new Error('Invalid proof nodes given') } @@ -114,10 +122,10 @@ export class Trie { * @method get * @memberof Trie * @param {Buffer} key - the key to search for - * @returns {Promise} - Returns a promise that resolves to `Buffer` if a value was found or `null` if no value was found. + * @returns {Buffer | null} - Returns `Buffer` if a value was found or `null` if no value was found. */ - async get(key: Buffer): Promise { - const { node, remaining } = await this.findPath(key) + get(key: Buffer): Buffer | null { + const { node, remaining } = this.findPath(key) let value = null if (node && remaining.length === 0) { value = node.value @@ -131,45 +139,39 @@ export class Trie { * @memberof Trie * @param {Buffer} key * @param {Buffer} value - * @returns {Promise} */ - async put(key: Buffer, value: Buffer): Promise { + put(key: Buffer, value: Buffer) { // If value is empty, delete if (!value || value.toString() === '') { - return await this.del(key) + return this.del(key) } - await this.lock.wait() if (this.root.equals(KECCAK256_RLP)) { // If no root, initialize this trie - await this._createInitialNode(key, value) + this._createInitialNode(key, value) } else { // First try to find the given key or its nearest node - const { remaining, stack } = await this.findPath(key) + const { remaining, stack } = this.findPath(key) // then update - await this._updateNode(key, value, remaining, stack) + this._updateNode(key, value, remaining, stack) } - this.lock.signal() } /** - * deletes a value given a `key` + * Deletes a value given a `key` * @method del * @memberof Trie * @param {Buffer} key - * @returns {Promise} */ - async del(key: Buffer): Promise { - await this.lock.wait() - const { node, stack } = await this.findPath(key) + del(key: Buffer) { + const { node, stack } = this.findPath(key) if (node) { - await this._deleteNode(key, stack) + this._deleteNode(key, stack) } - this.lock.signal() } - // retrieves a node from dbs by hash - async _lookupNode(node: Buffer | Buffer[]): Promise { + /** Retrieves a node from db by hash **/ + _lookupNode(node: Buffer | Buffer[]): TrieNode | null { if (isRawNode(node)) { return decodeRawNode(node as Buffer[]) } @@ -177,7 +179,7 @@ export class Trie { let value = null let foundNode = null - value = await this.db.get(node as Buffer) + value = this.db.get(node as Buffer) if (value) { foundNode = decodeNode(value) @@ -186,11 +188,11 @@ export class Trie { return foundNode } - // writes a single node to dbs - async _putNode(node: TrieNode): Promise { + /** Writes a single node to db **/ + _putNode(node: TrieNode) { const hash = node.hash() const serialized = node.serialize() - await this.db.put(hash, serialized) + this.db.put(hash, serialized) } /** @@ -199,91 +201,72 @@ export class Trie { * @method findPath * @memberof Trie * @param {Buffer} key - the search key - * @returns {Promise} */ - async findPath(key: Buffer): Promise { - return new Promise(async (resolve) => { - let stack: TrieNode[] = [] - let targetKey = bufferToNibbles(key) - - // walk trie and process nodes - await this._walkTrie(this.root, async (nodeRef, node, keyProgress, walkController) => { - const keyRemainder = targetKey.slice(matchingNibbleLength(keyProgress, targetKey)) - stack.push(node) - - if (node instanceof BranchNode) { - if (keyRemainder.length === 0) { - // we exhausted the key without finding a node - resolve({ node, remaining: [], stack }) - } else { - const branchIndex = keyRemainder[0] - const branchNode = node.getBranch(branchIndex) - if (!branchNode) { - // there are no more nodes to find and we didn't find the key - resolve({ node: null, remaining: keyRemainder, stack }) - } else { - // node found, continuing search - await walkController.only(branchIndex) - } - } - } else if (node instanceof LeafNode) { - if (doKeysMatch(keyRemainder, node.key)) { - // keys match, return node with empty key - resolve({ node, remaining: [], stack }) - } else { - // reached leaf but keys dont match - resolve({ node: null, remaining: keyRemainder, stack }) - } - } else if (node instanceof ExtensionNode) { - const matchingLen = matchingNibbleLength(keyRemainder, node.key) - if (matchingLen !== node.key.length) { - // keys don't match, fail - resolve({ node: null, remaining: keyRemainder, stack }) + findPath(key: Buffer): Path { + let stack: TrieNode[] = [] + let targetKey = bufferToNibbles(key) + + // walk trie and process nodes + const nodes = this._walkTrie(this.root, targetKey) + + for (const foundNode of nodes) { + const { node, key: keyProgress } = foundNode + + const keyRemainder = targetKey.slice(matchingNibbleLength(keyProgress, targetKey)) + stack.push(node) + if (node instanceof BranchNode) { + if (keyRemainder.length === 0) { + // we exhausted the key without finding a node + return { node, remaining: [], stack } + } else { + const branchIndex = keyRemainder[0] + const branchNode = node.getBranch(branchIndex) + if (!branchNode) { + // there are no more nodes to find and we didn't find the key + return { node: null, remaining: keyRemainder, stack } } else { - // keys match, continue search - await walkController.next() + // node found, continuing search } } - }) - - // Resolve if _walkTrie finishes without finding any nodes - resolve({ node: null, remaining: [], stack }) - }) - } - - /* - * Finds all nodes that store k,v values - */ - async _findValueNodes(onFound: FoundNode): Promise { - await this._walkTrie(this.root, async (nodeRef, node, key, walkController) => { - let fullKey = key - - if (node instanceof LeafNode) { - fullKey = key.concat(node.key) - // found leaf node! - onFound(nodeRef, node, fullKey, walkController) - } else if (node instanceof BranchNode && node.value) { - // found branch with value - onFound(nodeRef, node, fullKey, walkController) - } else { - // keep looking for value nodes - await walkController.next() + } else if (node instanceof LeafNode) { + if (doKeysMatch(keyRemainder, node.key)) { + // keys match, return node with empty key + return { node, remaining: [], stack } + } else { + // reached leaf but keys dont match + return { node: null, remaining: keyRemainder, stack } + } + } else if (node instanceof ExtensionNode) { + const matchingLen = matchingNibbleLength(keyRemainder, node.key) + if (matchingLen !== node.key.length) { + // keys don't match, fail + return { node: null, remaining: keyRemainder, stack } + } else { + // keys match, continue search + } } - }) + } + + // Return if _walkTrie finishes without finding any nodes + return { node: null, remaining: [], stack } } /* * Finds all nodes that are stored directly in the db * (some nodes are stored raw inside other nodes) */ - async _findDbNodes(onFound: FoundNode): Promise { - await this._walkTrie(this.root, async (nodeRef, node, key, walkController) => { + _findDbNodes(): FoundNode[] { + const foundDbNodes: FoundNode[] = [] + const nodes = this._walkTrie(this.root) + for (const foundNode of nodes) { + const { nodeRef, node, key } = foundNode if (isRawNode(nodeRef)) { - await walkController.next() + // look for next } else { - onFound(nodeRef, node, key, walkController) + foundDbNodes.push({ nodeRef, node, key }) } - }) + } + return foundDbNodes } /** @@ -292,16 +275,10 @@ export class Trie { * @private * @param {Buffer} key * @param {Buffer} value - * @param {number[]} keyRemainder + * @param {Nibbles} keyRemainder * @param {TrieNode[]} stack - * @returns {Promise} */ - async _updateNode( - k: Buffer, - value: Buffer, - keyRemainder: number[], - stack: TrieNode[], - ): Promise { + _updateNode(k: Buffer, value: Buffer, keyRemainder: Nibbles, stack: TrieNode[]) { const toSave: BatchDBOp[] = [] const lastNode = stack.pop() if (!lastNode) { @@ -392,7 +369,7 @@ export class Trie { } } - await this._saveStack(key, stack, toSave) + this._saveStack(key, stack, toSave) } /** @@ -400,99 +377,61 @@ export class Trie { * @method _walkTrie * @private * @param {Buffer} root - * @param {Function} onNode - callback to call when a node is found - * @returns {Promise} - returns when finished walking trie + * @param {Nibbles} targetKey + * @returns {FoundNode[]} - An array of nodes found */ - async _walkTrie(root: Buffer, onNode: FoundNode): Promise { - return new Promise(async (resolve) => { - const self = this - root = root || this.root + _walkTrie(root: Buffer, targetKey?: Nibbles): FoundNode[] { + const self = this + root = root || this.root + const nodes: FoundNode[] = [] - if (root.equals(KECCAK256_RLP)) { - return resolve() - } + if (root.equals(KECCAK256_RLP)) { + return [] + } - // The maximum pool size should be high enough to utilize - // the parallelizability of reading nodes from disk and - // low enough to utilize the prioritisation of node lookup. - const maxPoolSize = 500 - const taskExecutor = new PrioritizedTaskExecutor(maxPoolSize) - - const processNode = async ( - nodeRef: Buffer, - node: TrieNode, - key: number[] = [], - ): Promise => { - const walkController = { - next: async () => { - if (node instanceof LeafNode) { - if (taskExecutor.finished()) { - resolve() - } - return - } - let children - if (node instanceof ExtensionNode) { - children = [[node.key, node.value]] - } else if (node instanceof BranchNode) { - children = node.getChildren().map((b) => [[b[0]], b[1]]) - } - if (!children) { - // Node has no children - return resolve() - } - for (const child of children) { - const keyExtension = child[0] as number[] - const childRef = child[1] as Buffer - const childKey = key.concat(keyExtension) - const priority = childKey.length - taskExecutor.execute(priority, async (taskCallback: Function) => { - const childNode = await self._lookupNode(childRef) - taskCallback() - if (childNode) { - processNode(childRef, childNode as TrieNode, childKey) - } - }) - } - }, - only: async (childIndex: number) => { - if (!(node instanceof BranchNode)) { - throw new Error('Expected branch node') - } - const childRef = node.getBranch(childIndex) - if (!childRef) { - throw new Error('Could not get branch of childIndex') - } - const childKey = key.slice() - childKey.push(childIndex) - const priority = childKey.length - taskExecutor.execute(priority, async (taskCallback: Function) => { - const childNode = await self._lookupNode(childRef) - taskCallback() - if (childNode) { - await processNode(childRef as Buffer, childNode, childKey) - } else { - // could not find child node - resolve() - } - }) - }, - } + const processNode = (nodeRef: Buffer, node: TrieNode, key: Nibbles = []) => { + if (node) { + nodes.push({ nodeRef, node, key }) + } - if (node) { - onNode(nodeRef, node, key, walkController) - } else { - resolve() - } + if (node instanceof LeafNode) { + return } - const node = await this._lookupNode(root) - if (node) { - await processNode(root, node as TrieNode, []) + // Process children + let children: Array<[Nibbles, Buffer | Buffer[]]> + if (node instanceof ExtensionNode) { + children = [[node.key, node.value]] + } else if (node instanceof BranchNode) { + children = node.getChildren().map((b) => [[b[0]], b[1]]) } else { - resolve() + // Node has no children + return } - }) + for (const [keyExtension, childRef] of children) { + const childKey = key.concat(keyExtension) + + if (targetKey) { + let matchingTarget = [...targetKey] + // setting array.length is a fast way to shorten it + matchingTarget.length = childKey.length + // stringifying the arrays is an easy way to compare their items in sequence + if (matchingTarget.toString() !== childKey.toString()) { + // Skip child if not relevant + continue + } + } + const childNode = self._lookupNode(childRef) + processNode(childRef as Buffer, childNode as TrieNode, childKey) + } + } + + const node = this._lookupNode(root) + if (node) { + processNode(root, node as TrieNode, []) + } + + return nodes } /** @@ -502,9 +441,8 @@ export class Trie { * @param {Array} key - the key. Should follow the stack * @param {Array} stack - a stack of nodes to the value given by the key * @param {Array} opStack - a stack of levelup operations to commit at the end of this funciton - * @returns {Promise} */ - async _saveStack(key: number[], stack: TrieNode[], opStack: BatchDBOp[]): Promise { + _saveStack(key: Nibbles, stack: TrieNode[], opStack: BatchDBOp[]) { let lastRoot // update nodes @@ -530,12 +468,12 @@ export class Trie { this.root = lastRoot } - await this.db.batch(opStack) + this.db.batch(opStack) } - async _deleteNode(k: Buffer, stack: TrieNode[]): Promise { + _deleteNode(k: Buffer, stack: TrieNode[]) { const processBranchNode = ( - key: number[], + key: Nibbles, branchKey: number, branchNode: TrieNode, parentNode: TrieNode, @@ -632,7 +570,7 @@ export class Trie { const branchNodeKey = branchNodes[0][0] // look up node - const foundNode = await this._lookupNode(branchNode) + const foundNode = this._lookupNode(branchNode) if (foundNode) { key = processBranchNode( key, @@ -641,7 +579,7 @@ export class Trie { parentNode as TrieNode, stack, ) - await this._saveStack(key, stack, opStack) + this._saveStack(key, stack, opStack) } } else { // simple removing a leaf and recaluclation the stack @@ -650,19 +588,19 @@ export class Trie { } stack.push(lastNode) - await this._saveStack(key, stack, opStack) + this._saveStack(key, stack, opStack) } } - // Creates the initial node from an empty tree - async _createInitialNode(key: Buffer, value: Buffer): Promise { + /** Creates the initial node from an empty tree **/ + _createInitialNode(key: Buffer, value: Buffer) { const newNode = new LeafNode(bufferToNibbles(key), value) this.root = newNode.hash() - await this._putNode(newNode) + this._putNode(newNode) } /** - * Formats node to be saved by levelup.batch. + * Formats node to be saved by db.batch. * @method _formatNode * @private * @param {TrieNode} node - the node to format @@ -692,21 +630,11 @@ export class Trie { return node.raw() } - /** - * The `data` event is given an `Object` that has two properties; the `key` and the `value`. Both should be Buffers. - * @method createReadStream - * @memberof Trie - * @return {stream.Readable} Returns a [stream](https://nodejs.org/dist/latest-v5.x/docs/api/stream.html#stream_class_stream_readable) of the contents of the `trie` - */ - createReadStream(): ReadStream { - return new ReadStream(this) - } - // creates a new trie backed by the same db // and starting at the same root copy(): Trie { const db = this.db.copy() - return new Trie(db._leveldb, this.root) + return new Trie(db._map, this.root) } /** @@ -721,19 +649,18 @@ export class Trie { * , { type: 'put', key: Buffer.from('spouse'), value: Buffer.from('Kim Young-sook') } * , { type: 'put', key: Buffer.from('occupation'), value: Buffer.from('Clown') } * ] - * await trie.batch(ops) + * trie.batch(ops) * @param {Array} ops - * @returns {Promise} */ - async batch(ops: BatchDBOp[]): Promise { - for await (const op of ops) { + batch(ops: BatchDBOp[]) { + for (const op of ops) { if (op.type === 'put') { if (!op.value) { throw new Error('Invalid batch db operation') } - await this.put(op.key, op.value) + this.put(op.key, op.value) } else if (op.type === 'del') { - await this.del(op.key) + this.del(op.key) } } } @@ -741,8 +668,8 @@ export class Trie { /** * Checks if a given root exists. */ - async checkRoot(root: Buffer): Promise { - const value = await this._lookupNode(root) + checkRoot(root: Buffer): boolean { + const value = this._lookupNode(root) return !!value } } diff --git a/src/checkpointTrie.ts b/src/checkpointTrie.ts index 459ff38..a10b711 100644 --- a/src/checkpointTrie.ts +++ b/src/checkpointTrie.ts @@ -1,9 +1,7 @@ import { Trie as BaseTrie } from './baseTrie' -import { ScratchReadStream } from './scratchReadStream' import { ScratchDB } from './scratch' import { DB, BatchDBOp } from './db' import { TrieNode } from './trieNode' -const WriteStream = require('level-ws') export class CheckpointTrie extends BaseTrie { _mainDB: DB @@ -30,8 +28,7 @@ export class CheckpointTrie extends BaseTrie { /** * Creates a checkpoint that can later be reverted to or committed. * After this is called, no changes to the trie will be permanently saved - * until `commit` is called. Calling `putRaw` overrides the checkpointing - * mechanism and would directly write to db. + * until `commit` is called. */ checkpoint() { const wasCheckpoint = this.isCheckpoint @@ -47,22 +44,17 @@ export class CheckpointTrie extends BaseTrie { * Commits a checkpoint to disk, if current checkpoint is not nested. If * nested, only sets the parent checkpoint as current checkpoint. * @method commit - * @returns {Promise} * @throws If not during a checkpoint phase */ - async commit(): Promise { + commit() { if (!this.isCheckpoint) { throw new Error('trying to commit when not checkpointed') } - await this.lock.wait() - this._checkpoints.pop() if (!this.isCheckpoint) { - await this._exitCpMode(true) + this._exitCpMode(true) } - - this.lock.signal() } /** @@ -70,15 +62,13 @@ export class CheckpointTrie extends BaseTrie { * If during a nested checkpoint, sets root to most recent checkpoint, and sets * parent checkpoint as current. */ - async revert(): Promise { - await this.lock.wait() + revert() { if (this.isCheckpoint) { this.root = this._checkpoints.pop()! if (!this.isCheckpoint) { - await this._exitCpMode(false) + this._exitCpMode(false) } } - this.lock.signal() } /** @@ -90,7 +80,7 @@ export class CheckpointTrie extends BaseTrie { */ copy(includeCheckpoints: boolean = true): CheckpointTrie { const db = this._mainDB.copy() - const trie = new CheckpointTrie(db._leveldb, this.root) + const trie = new CheckpointTrie(db._map, this.root) if (includeCheckpoints && this.isCheckpoint) { trie._checkpoints = this._checkpoints.slice() trie._scratch = this._scratch!.copy() @@ -112,40 +102,46 @@ export class CheckpointTrie extends BaseTrie { * Exit from checkpoint mode. * @private */ - async _exitCpMode(commitState: boolean): Promise { - return new Promise(async (resolve) => { - const scratch = this._scratch as ScratchDB - this._scratch = null - this.db = this._mainDB - - if (commitState) { - this._createScratchReadStream(scratch) - .pipe(WriteStream(this.db._leveldb)) - .on('close', resolve) - } else { - process.nextTick(resolve) - } - }) + _exitCpMode(commitState: boolean) { + const scratch = this._scratch as ScratchDB + this._scratch = null + this.db = this._mainDB + + if (commitState) { + this._commitChanges(scratch) + } } /** - * Returns a `ScratchReadStream` based on the state updates - * since checkpoint. - * @method createScratchReadStream + * Commits changes based on the state updates since checkpoint. + * @method _commitChanges + * @param {ScratchDB} scratchDb * @private */ - _createScratchReadStream(scratchDb?: ScratchDB) { + _commitChanges(scratchDb?: ScratchDB) { let scratch = scratchDb || this._scratch if (!scratch) { throw new Error('No scratch found to use') } - const trie = new BaseTrie(scratch._leveldb, this.root) + const trie = new BaseTrie(scratch._map, this.root) trie.db = scratch - return new ScratchReadStream(trie) + + const batchOps: BatchDBOp[] = [] + const nodes = trie._findDbNodes() + for (const foundNode of nodes) { + const { nodeRef, node } = foundNode + batchOps.push({ + type: 'put', + key: nodeRef, + value: node.serialize(), + }) + } + + this.db.batch(batchOps) } /** - * Formats node to be saved by levelup.batch. + * Formats node to be saved by db.batch. * @method _formatNode * @private * @param {TrieNode} node - the node to format diff --git a/src/db.ts b/src/db.ts index 659cc32..e66034f 100644 --- a/src/db.ts +++ b/src/db.ts @@ -1,7 +1,6 @@ import { LevelUp } from 'levelup' -const level = require('level-mem') -export const ENCODING_OPTS = { keyEncoding: 'binary', valueEncoding: 'binary' } +export type DBMap = Map export type BatchDBOp = PutBatch | DelBatch export interface PutBatch { @@ -14,50 +13,57 @@ export interface DelBatch { key: Buffer } +/** Options to be passed in the constructor of a new DB */ +export interface DBOptions { + /** The db may be initialized with an existing JavaScript map. **/ + map?: Map + /** The db may be initialized with an abstract-leveldown compliant store. **/ + leveldb?: LevelUp +} + /** - * DB is a thin wrapper around the underlying levelup db, - * which validates inputs and sets encoding type. + * DB is a thin wrapper around JavaScript's map data structure. */ export class DB { - _leveldb: LevelUp + _map: DBMap /** - * Initialize a DB instance. If `leveldb` is not provided, DB - * defaults to an [in-memory store](https://github.com/Level/memdown). - * @param {Object} [leveldb] - An abstract-leveldown compliant store + * Initialize a DB instance with [[DBOptions]]. + * If `leveldb` is not provided, db defaults to an in-memory JavaScript map. */ - constructor(leveldb?: LevelUp) { - this._leveldb = leveldb || level() + constructor(options?: DBOptions) { + if (options?.map) { + this._map = options.map + } else if (options?.leveldb) { + this._map = new Map() + // TODO one idea to resolve this async init race condition: create a public API method for _leveldbToMap and expect the result of that to be passed into `Trie(db)`. + this._leveldbToMap(options.leveldb).then((dbMap) => { + this._map = dbMap + }) + } else { + this._map = new Map() + } } /** - * Retrieves a raw value from leveldb. + * Retrieves a raw value from db. * @param {Buffer} key - * @returns {Promise} - Promise resolves with `Buffer` if a value is found or `null` if no value is found. + * @returns {Buffer | null} - Returns with `Buffer` if a value is found or `null` if no value is found. */ - async get(key: Buffer): Promise { - let value = null - try { - value = await this._leveldb.get(key, ENCODING_OPTS) - } catch (error) { - if (error.notFound) { - // not found, returning null - } else { - throw error - } - } finally { - return value - } + get(key: Buffer): Buffer | null { + const formattedKey = key.toString('hex') + const value = this._map.get(formattedKey) + return value || null } /** - * Writes a value directly to leveldb. - * @param {Buffer} key The key as a `Buffer` - * @param {Buffer} value The value to be stored - * @returns {Promise} + * Writes a value to db. + * @param {Buffer} key - The key to be stored + * @param {Buffer} value - The value to be stored */ - async put(key: Buffer, val: Buffer): Promise { - await this._leveldb.put(key, val, ENCODING_OPTS) + put(key: Buffer, value: Buffer) { + const formattedKey = key.toString('hex') + this._map.set(formattedKey, value) } /** @@ -65,24 +71,54 @@ export class DB { * @param {Buffer} key * @returns {Promise} */ - async del(key: Buffer): Promise { - await this._leveldb.del(key, ENCODING_OPTS) + del(key: Buffer) { + const formattedKey = key.toString('hex') + this._map.delete(formattedKey) } /** * Performs a batch operation on db. - * @param {Array} opStack A stack of levelup operations - * @returns {Promise} + * @param {Array} opStack A stack of db operations */ - async batch(opStack: BatchDBOp[]): Promise { - await this._leveldb.batch(opStack, ENCODING_OPTS) + batch(opStack: BatchDBOp[]) { + for (const op of opStack) { + if (op.type === 'put') { + this.put(op.key, op.value) + } else { + // delete + this.del(op.key) + } + } } /** * Returns a copy of the DB instance, with a reference - * to the **same** underlying leveldb instance. + * to the **same** underlying db instance. */ copy(): DB { - return new DB(this._leveldb) + return new DB({ map: this._map }) + } + + /** + * Creates a [[DBMap]] instance by iterating through a leveldb. + * @private + * @param {LevelUp} db - An abstract-leveldown compliant store. + */ + async _leveldbToMap(db: LevelUp): Promise { + return new Promise((resolve) => { + const dbMap = new Map() + + db.createReadStream() + .on('data', (data) => { + const formattedKey = data.key.toString('hex') + dbMap.set(formattedKey, data.value) + }) + .on('error', (err) => { + throw err + }) + .on('end', () => { + resolve(dbMap) + }) + }) } } diff --git a/src/prioritizedTaskExecutor.ts b/src/prioritizedTaskExecutor.ts deleted file mode 100644 index 47bcb58..0000000 --- a/src/prioritizedTaskExecutor.ts +++ /dev/null @@ -1,56 +0,0 @@ -interface Task { - priority: number - fn: Function -} - -export class PrioritizedTaskExecutor { - private maxPoolSize: number - private currentPoolSize: number - private queue: Task[] - - /** - * Executes tasks up to maxPoolSize at a time, other items are put in a priority queue. - * @class PrioritizedTaskExecutor - * @private - * @param {Number} maxPoolSize The maximum size of the pool - * @prop {Number} maxPoolSize The maximum size of the pool - * @prop {Number} currentPoolSize The current size of the pool - * @prop {Array} queue The task queue - */ - constructor(maxPoolSize: number) { - this.maxPoolSize = maxPoolSize - this.currentPoolSize = 0 - this.queue = [] - } - - /** - * Executes the task. - * @private - * @param {Number} priority The priority of the task - * @param {Function} fn The function that accepts the callback, which must be called upon the task completion. - */ - execute(priority: number, fn: Function) { - if (this.currentPoolSize < this.maxPoolSize) { - this.currentPoolSize++ - fn(() => { - this.currentPoolSize-- - if (this.queue.length > 0) { - this.queue.sort((a, b) => b.priority - a.priority) - const item = this.queue.shift() - this.execute(item!.priority, item!.fn) - } - }) - } else { - this.queue.push({ priority, fn }) - } - } - - /** - * Checks if the taskExecutor is finished. - * @private - * @returns {Boolean} - Returns `true` if the taskExecutor is finished, otherwise returns `false`. - */ - finished(): boolean { - return this.currentPoolSize === 0 - } -} diff --git a/src/readStream.ts b/src/readStream.ts deleted file mode 100644 index 8ee3c78..0000000 --- a/src/readStream.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { nibblesToBuffer } from './util/nibbles' -import { Trie as BaseTrie } from './baseTrie' -const Readable = require('readable-stream').Readable - -export class TrieReadStream extends Readable { - private trie: BaseTrie - private _started: boolean - - constructor(trie: BaseTrie) { - super({ objectMode: true }) - - this.trie = trie - this._started = false - } - - async _read() { - if (this._started) { - return - } - this._started = true - await this.trie._findValueNodes(async (nodeRef, node, key, walkController) => { - this.push({ - key: nibblesToBuffer(key), - value: node.value, - }) - await walkController.next() - }) - this.push(null) - } -} diff --git a/src/scratch.ts b/src/scratch.ts index 88dbe42..f46a703 100644 --- a/src/scratch.ts +++ b/src/scratch.ts @@ -1,4 +1,4 @@ -import { DB, ENCODING_OPTS } from './db' +import { DB } from './db' /** * An in-memory wrap over `DB` with an upstream DB @@ -18,38 +18,22 @@ export class ScratchDB extends DB { * Similar to `DB.get`, but first searches in-memory * scratch DB, if key not found, searches upstream DB. */ - async get(key: Buffer): Promise { - let value = null + get(key: Buffer): Buffer | null { + const formattedKey = key.toString('hex') // First, search in-memory db - try { - value = await this._leveldb.get(key, ENCODING_OPTS) - } catch (error) { - if (error.notFound) { - // not found, returning null - } else { - throw error - } - } + let value = this._map.get(formattedKey) // If not found, try searching upstream db - if (!value && this._upstream._leveldb) { - try { - value = await this._upstream._leveldb.get(key, ENCODING_OPTS) - } catch (error) { - if (error.notFound) { - // not found, returning null - } else { - throw error - } - } + if (!value && this._upstream._map) { + value = this._upstream._map.get(formattedKey) } - return value + return value || null } copy(): ScratchDB { const scratch = new ScratchDB(this._upstream) - scratch._leveldb = this._leveldb + scratch._map = this._map return scratch } } diff --git a/src/scratchReadStream.ts b/src/scratchReadStream.ts deleted file mode 100644 index 9bc736d..0000000 --- a/src/scratchReadStream.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Trie as BaseTrie } from './baseTrie' -const Readable = require('readable-stream').Readable - -/* - * This is used to minimally dump the scratch into the db. - */ -export class ScratchReadStream extends Readable { - private trie: BaseTrie - private _started: boolean - - constructor(trie: BaseTrie) { - super({ objectMode: true }) - - this.trie = trie - this._started = false - } - - async _read() { - if (this._started) { - return - } - this._started = true - await this.trie._findDbNodes(async (nodeRef, node, key, walkController) => { - this.push({ - key: nodeRef, - value: node.serialize(), - }) - await walkController.next() - }) - this.push(null) - } -} diff --git a/src/secure.ts b/src/secure.ts index 3a6c22f..c45e113 100644 --- a/src/secure.ts +++ b/src/secure.ts @@ -14,12 +14,12 @@ export class SecureTrie extends CheckpointTrie { super(...args) } - static prove(trie: SecureTrie, key: Buffer): Promise { + static prove(trie: SecureTrie, key: Buffer): Buffer[] { const hash = keccak256(key) return super.prove(trie, hash) } - static async verifyProof(rootHash: Buffer, key: Buffer, proof: Buffer[]): Promise { + static verifyProof(rootHash: Buffer, key: Buffer, proof: Buffer[]): Buffer | null { const hash = keccak256(key) return super.verifyProof(rootHash, hash, proof) } @@ -27,12 +27,12 @@ export class SecureTrie extends CheckpointTrie { copy(): SecureTrie { const trie = super.copy(false) const db = trie.db.copy() - return new SecureTrie(db._leveldb, this.root) + return new SecureTrie(db._map, this.root) } - async get(key: Buffer): Promise { + get(key: Buffer): Buffer | null { const hash = keccak256(key) - const value = await super.get(hash) + const value = super.get(hash) return value } @@ -40,17 +40,17 @@ export class SecureTrie extends CheckpointTrie { * For a falsey value, use the original key * to avoid double hashing the key. */ - async put(key: Buffer, val: Buffer): Promise { + put(key: Buffer, val: Buffer) { if (!val || val.toString() === '') { - await this.del(key) + this.del(key) } else { const hash = keccak256(key) - await super.put(hash, val) + super.put(hash, val) } } - async del(key: Buffer): Promise { + del(key: Buffer) { const hash = keccak256(key) - await super.del(hash) + super.del(hash) } } diff --git a/src/util/hex.ts b/src/util/hex.ts index 17aa25a..ffae4ca 100644 --- a/src/util/hex.ts +++ b/src/util/hex.ts @@ -1,10 +1,13 @@ +import { Nibbles } from '../trieNode' + /** * Prepends hex prefix to an array of nibbles. * @method addHexPrefix - * @param {Array} Array of nibbles - * @returns {Array} - returns buffer of encoded data + * @param {Nibbles} key - Nibble array + * @param {boolean} terminator - if is for a terminating (leaf) node. + * @returns {Nibbles} - returns buffer of encoded data **/ -export function addHexPrefix(key: number[], terminator: boolean): number[] { +export function addHexPrefix(key: Nibbles, terminator: boolean): Nibbles { // odd if (key.length % 2) { key.unshift(1) @@ -24,10 +27,10 @@ export function addHexPrefix(key: number[], terminator: boolean): number[] { /** * Removes hex prefix of an array of nibbles. * @method removeHexPrefix - * @param {Array} Array of nibbles + * @param {Nibbles} val - Array of nibbles * @private */ -export function removeHexPrefix(val: number[]): number[] { +export function removeHexPrefix(val: Nibbles): Nibbles { if (val[0] % 2) { val = val.slice(1) } else { @@ -40,9 +43,9 @@ export function removeHexPrefix(val: number[]): number[] { /** * Returns true if hexprefixed path is for a terminating (leaf) node. * @method isTerminator - * @param {Array} key - an hexprefixed array of nibbles + * @param {Nibbles} key - a hexprefixed array of nibbles * @private */ -export function isTerminator(key: number[]): boolean { +export function isTerminator(key: Nibbles): boolean { return key[0] > 1 } diff --git a/src/util/nibbles.ts b/src/util/nibbles.ts index c5723d0..358cd8d 100644 --- a/src/util/nibbles.ts +++ b/src/util/nibbles.ts @@ -1,10 +1,12 @@ +import { Nibbles } from '../trieNode' + /** * Converts a buffer to a nibble array. * @method bufferToNibbles * @param {Buffer} key * @private */ -export function bufferToNibbles(key: Buffer): number[] { +export function bufferToNibbles(key: Buffer): Nibbles { const bkey = Buffer.from(key) let nibbles = [] as any @@ -21,14 +23,14 @@ export function bufferToNibbles(key: Buffer): number[] { /** * Converts a nibble array into a buffer. * @method nibblesToBuffer - * @param {Array} Nibble array + * @param {Nibbles} nib - Nibble array * @private */ -export function nibblesToBuffer(arr: number[]): Buffer { - let buf = Buffer.alloc(arr.length / 2) +export function nibblesToBuffer(nib: Nibbles): Buffer { + let buf = Buffer.alloc(nib.length / 2) for (let i = 0; i < buf.length; i++) { let q = i * 2 - buf[i] = (arr[q] << 4) + arr[++q] + buf[i] = (nib[q] << 4) + nib[++q] } return buf } @@ -36,11 +38,11 @@ export function nibblesToBuffer(arr: number[]): Buffer { /** * Returns the number of in order matching nibbles of two give nibble arrays. * @method matchingNibbleLength - * @param {Array} nib1 - * @param {Array} nib2 + * @param {Nibbles} nib1 + * @param {Nibbles} nib2 * @private */ -export function matchingNibbleLength(nib1: number[], nib2: number[]): number { +export function matchingNibbleLength(nib1: Nibbles, nib2: Nibbles): number { let i = 0 while (nib1[i] === nib2[i] && nib1.length > i) { i++ @@ -50,10 +52,10 @@ export function matchingNibbleLength(nib1: number[], nib2: number[]): number { /** * Compare two nibble array keys. - * @param {Array} keyA - * @param {Array} keyB + * @param {Nibbles} keyA + * @param {Nibbles} keyB */ -export function doKeysMatch(keyA: number[], keyB: number[]): boolean { +export function doKeysMatch(keyA: Nibbles, keyB: Nibbles): boolean { const length = matchingNibbleLength(keyA, keyB) return length === keyA.length && length === keyB.length } diff --git a/test/checkpoint.spec.ts b/test/checkpoint.spec.ts index 61dc410..c542c9c 100644 --- a/test/checkpoint.spec.ts +++ b/test/checkpoint.spec.ts @@ -9,18 +9,18 @@ tape('testing checkpoints', function (tester) { let preRoot: String let postRoot: String - it('setup', async function (t) { + it('setup', function (t) { trie = new CheckpointTrie() - await trie.put(Buffer.from('do'), Buffer.from('verb')) - await trie.put(Buffer.from('doge'), Buffer.from('coin')) + trie.put(Buffer.from('do'), Buffer.from('verb')) + trie.put(Buffer.from('doge'), Buffer.from('coin')) preRoot = trie.root.toString('hex') t.end() }) - it('should copy trie and get value before checkpoint', async function (t) { + it('should copy trie and get value before checkpoint', function (t) { trieCopy = trie.copy() t.equal(trieCopy.root.toString('hex'), preRoot) - const res = await trieCopy.get(Buffer.from('do')) + const res = trieCopy.get(Buffer.from('do')) t.ok(Buffer.from('verb').equals(Buffer.from(res!))) t.end() }) @@ -31,76 +31,76 @@ tape('testing checkpoints', function (tester) { t.end() }) - it('should save to the cache', async function (t) { - await trie.put(Buffer.from('test'), Buffer.from('something')) - await trie.put(Buffer.from('love'), Buffer.from('emotion')) + it('should save to the cache', function (t) { + trie.put(Buffer.from('test'), Buffer.from('something')) + trie.put(Buffer.from('love'), Buffer.from('emotion')) postRoot = trie.root.toString('hex') t.end() }) - it('should get values from before checkpoint', async function (t) { - const res = await trie.get(Buffer.from('doge')) + it('should get values from before checkpoint', function (t) { + const res = trie.get(Buffer.from('doge')) t.ok(Buffer.from('coin').equals(Buffer.from(res!))) t.end() }) - it('should get values from cache', async function (t) { - const res = await trie.get(Buffer.from('love')) + it('should get values from cache', function (t) { + const res = trie.get(Buffer.from('love')) t.ok(Buffer.from('emotion').equals(Buffer.from(res!))) t.end() }) - it('should copy trie and get upstream and cache values after checkpoint', async function (t) { + it('should copy trie and get upstream and cache values after checkpoint', function (t) { trieCopy = trie.copy() t.equal(trieCopy.root.toString('hex'), postRoot) t.equal(trieCopy._checkpoints.length, 1) t.ok(trieCopy.isCheckpoint) - const res = await trieCopy.get(Buffer.from('do')) + const res = trieCopy.get(Buffer.from('do')) t.ok(Buffer.from('verb').equals(Buffer.from(res!))) - const res2 = await trieCopy.get(Buffer.from('love')) + const res2 = trieCopy.get(Buffer.from('love')) t.ok(Buffer.from('emotion').equals(Buffer.from(res2!))) t.end() }) - it('should revert to the orginal root', async function (t) { + it('should revert to the orginal root', function (t) { t.ok(trie.isCheckpoint) - await trie.revert() + trie.revert() t.equal(trie.root.toString('hex'), preRoot) t.notOk(trie.isCheckpoint) t.end() }) - it('should not get values from cache after revert', async function (t) { - const res = await trie.get(Buffer.from('love')) + it('should not get values from cache after revert', function (t) { + const res = trie.get(Buffer.from('love')) t.notOk(res) t.end() }) - it('should commit a checkpoint', async function (t) { + it('should commit a checkpoint', function (t) { trie.checkpoint() - await trie.put(Buffer.from('test'), Buffer.from('something')) - await trie.put(Buffer.from('love'), Buffer.from('emotion')) - await trie.commit() + trie.put(Buffer.from('test'), Buffer.from('something')) + trie.put(Buffer.from('love'), Buffer.from('emotion')) + trie.commit() t.equal(trie.isCheckpoint, false) t.equal(trie.root.toString('hex'), postRoot) t.end() }) - it('should get new values after commit', async function (t) { - const res = await trie.get(Buffer.from('love')) + it('should get new values after commit', function (t) { + const res = trie.get(Buffer.from('love')) t.ok(Buffer.from('emotion').equals(Buffer.from(res!))) t.end() }) - it('should commit a nested checkpoint', async function (t) { + it('should commit a nested checkpoint', function (t) { trie.checkpoint() let root: Buffer - await trie.put(Buffer.from('test'), Buffer.from('something else')) + trie.put(Buffer.from('test'), Buffer.from('something else')) root = trie.root trie.checkpoint() - await trie.put(Buffer.from('the feels'), Buffer.from('emotion')) - await trie.revert() - await trie.commit() + trie.put(Buffer.from('the feels'), Buffer.from('emotion')) + trie.revert() + trie.commit() t.equal(trie.isCheckpoint, false) t.equal(trie.root.toString('hex'), root.toString('hex')) t.end() diff --git a/test/db.spec.ts b/test/db.spec.ts index cff5d2e..84a0b25 100644 --- a/test/db.spec.ts +++ b/test/db.spec.ts @@ -7,29 +7,29 @@ tape('DB basic functionality', (t) => { const k = Buffer.from('foo') const v = Buffer.from('bar') - t.test('puts and gets value', async (st) => { - await db.put(k, v) - const res = await db.get(k) + t.test('puts and gets value', (st) => { + db.put(k, v) + const res = db.get(k) st.ok(v.equals(res!)) st.end() }) - t.test('dels value', async (st) => { - await db.del(k) - const res = await db.get(k) + t.test('dels value', (st) => { + db.del(k) + const res = db.get(k) st.notOk(res) st.end() }) - t.test('batch ops', async (st) => { + t.test('batch ops', (st) => { const k2 = Buffer.from('bar') const v2 = Buffer.from('baz') const ops = [ { type: 'put', key: k, value: v }, { type: 'put', key: k2, value: v2 }, ] as BatchDBOp[] - await db.batch(ops) - const res = await db.get(k2) + db.batch(ops) + const res = db.get(k2) st.ok(v2.equals(res!)) st.end() }) diff --git a/test/encoding.spec.ts b/test/encoding.spec.ts index 3148c0b..9fd810a 100644 --- a/test/encoding.spec.ts +++ b/test/encoding.spec.ts @@ -6,9 +6,9 @@ const trie = new CheckpointTrie() const trie2 = new CheckpointTrie() const hex = 'FF44A3B3' -tape('encoding hexprefixes', async function (t) { - await trie.put(Buffer.from(hex, 'hex'), Buffer.from('test')) - await trie2.put(toBuffer(`0x${hex}`), Buffer.from('test')) +tape('encoding hexprefixes', function (t) { + trie.put(Buffer.from(hex, 'hex'), Buffer.from('test')) + trie2.put(toBuffer(`0x${hex}`), Buffer.from('test')) t.equal(trie.root.toString('hex'), trie2.root.toString('hex')) t.end() }) diff --git a/test/index.spec.ts b/test/index.spec.ts index b059240..41471fd 100644 --- a/test/index.spec.ts +++ b/test/index.spec.ts @@ -1,3 +1,5 @@ +const Buffer = require('buffer').Buffer // needed for karma + import * as tape from 'tape' import * as rlp from 'rlp' import { KECCAK256_NULL } from 'ethereumjs-util' @@ -6,57 +8,57 @@ import { CheckpointTrie } from '../src' tape('simple save and retrive', function (tester) { const it = tester.test - it('should not crash if given a non-existant root', async function (t) { + it('should not crash if given a non-existant root', function (t) { const root = Buffer.from( '3f4399b08efe68945c1cf90ffe85bbe3ce978959da753f9e649f034015b8817d', 'hex', ) const trie = new CheckpointTrie(null, root) - const value = await trie.get(Buffer.from('test')) + const value = trie.get(Buffer.from('test')) t.equal(value, null) t.end() }) const trie = new CheckpointTrie() - it('save a value', async function (t) { - await trie.put(Buffer.from('test'), Buffer.from('one')) + it('save a value', function (t) { + trie.put(Buffer.from('test'), Buffer.from('one')) t.end() }) - it('should get a value', async function (t) { - const value = await trie.get(Buffer.from('test')) + it('should get a value', function (t) { + const value = trie.get(Buffer.from('test')) t.equal(value!.toString(), 'one') t.end() }) - it('should update a value', async function (t) { - await trie.put(Buffer.from('test'), Buffer.from('two')) - const value = await trie.get(Buffer.from('test')) + it('should update a value', function (t) { + trie.put(Buffer.from('test'), Buffer.from('two')) + const value = trie.get(Buffer.from('test')) t.equal(value!.toString(), 'two') t.end() }) - it('should delete a value', async function (t) { - await trie.del(Buffer.from('test')) - const value = await trie.get(Buffer.from('test')) + it('should delete a value', function (t) { + trie.del(Buffer.from('test')) + const value = trie.get(Buffer.from('test')) t.notok(value) t.end() }) - it('should recreate a value', async function (t) { - await trie.put(Buffer.from('test'), Buffer.from('one')) + it('should recreate a value', function (t) { + trie.put(Buffer.from('test'), Buffer.from('one')) t.end() }) - it('should get updated a value', async function (t) { - const value = await trie.get(Buffer.from('test')) + it('should get updated a value', function (t) { + const value = trie.get(Buffer.from('test')) t.equal(value!.toString(), 'one') t.end() }) - it('should create a branch here', async function (t) { - await trie.put(Buffer.from('doge'), Buffer.from('coin')) + it('should create a branch here', function (t) { + trie.put(Buffer.from('doge'), Buffer.from('coin')) t.equal( 'de8a34a8c1d558682eae1528b47523a483dd8685d6db14b291451a66066bf0fc', trie.root.toString('hex'), @@ -64,40 +66,40 @@ tape('simple save and retrive', function (tester) { t.end() }) - it('should get a value that is in a branch', async function (t) { - const value = await trie.get(Buffer.from('doge')) + it('should get a value that is in a branch', function (t) { + const value = trie.get(Buffer.from('doge')) t.equal(value!.toString(), 'coin') t.end() }) - it('should delete from a branch', async function (t) { - await trie.del(Buffer.from('doge')) - const value = await trie.get(Buffer.from('doge')) + it('should delete from a branch', function (t) { + trie.del(Buffer.from('doge')) + const value = trie.get(Buffer.from('doge')) t.equal(value, null) t.end() }) - tape('storing longer values', async function (tester) { + tape('storing longer values', function (tester) { const it = tester.test const trie = new CheckpointTrie() const longString = 'this will be a really really really long value' const longStringRoot = 'b173e2db29e79c78963cff5196f8a983fbe0171388972106b114ef7f5c24dfa3' - it('should store a longer string', async function (t) { - await trie.put(Buffer.from('done'), Buffer.from(longString)) - await trie.put(Buffer.from('doge'), Buffer.from('coin')) + it('should store a longer string', function (t) { + trie.put(Buffer.from('done'), Buffer.from(longString)) + trie.put(Buffer.from('doge'), Buffer.from('coin')) t.equal(longStringRoot, trie.root.toString('hex')) t.end() }) - it('should retreive a longer value', async function (t) { - const value = await trie.get(Buffer.from('done')) + it('should retreive a longer value', function (t) { + const value = trie.get(Buffer.from('done')) t.equal(value!.toString(), longString) t.end() }) - it('should when being modiefied delete the old value', async function (t) { - await trie.put(Buffer.from('done'), Buffer.from('test')) + it('should when being modiefied delete the old value', function (t) { + trie.put(Buffer.from('done'), Buffer.from('test')) t.end() }) }) @@ -106,13 +108,13 @@ tape('simple save and retrive', function (tester) { const it = tester.test const trie = new CheckpointTrie() - it('should store a value', async function (t) { - await trie.put(Buffer.from('doge'), Buffer.from('coin')) + it('should store a value', function (t) { + trie.put(Buffer.from('doge'), Buffer.from('coin')) t.end() }) - it('should create extension to store this value', async function (t) { - await trie.put(Buffer.from('do'), Buffer.from('verb')) + it('should create extension to store this value', function (t) { + trie.put(Buffer.from('do'), Buffer.from('verb')) t.equal( 'f803dfcb7e8f1afd45e88eedb4699a7138d6c07b71243d9ae9bff720c99925f9', trie.root.toString('hex'), @@ -120,8 +122,8 @@ tape('simple save and retrive', function (tester) { t.end() }) - it('should store this value under the extension', async function (t) { - await trie.put(Buffer.from('done'), Buffer.from('finished')) + it('should store this value under the extension', function (t) { + trie.put(Buffer.from('done'), Buffer.from('finished')) t.equal( '409cff4d820b394ed3fb1cd4497bdd19ffa68d30ae34157337a7043c94a3e8cb', trie.root.toString('hex'), @@ -134,18 +136,18 @@ tape('simple save and retrive', function (tester) { const it = tester.test const trie = new CheckpointTrie() - it('should create extension to store this value', async function (t) { - await trie.put(Buffer.from('do'), Buffer.from('verb')) + it('should create extension to store this value', function (t) { + trie.put(Buffer.from('do'), Buffer.from('verb')) t.end() }) - it('should store a value', async function (t) { - await trie.put(Buffer.from('doge'), Buffer.from('coin')) + it('should store a value', function (t) { + trie.put(Buffer.from('doge'), Buffer.from('coin')) t.end() }) - it('should store this value under the extension', async function (t) { - await trie.put(Buffer.from('done'), Buffer.from('finished')) + it('should store this value under the extension', function (t) { + trie.put(Buffer.from('done'), Buffer.from('finished')) t.equal( '409cff4d820b394ed3fb1cd4497bdd19ffa68d30ae34157337a7043c94a3e8cb', trie.root.toString('hex'), @@ -159,50 +161,50 @@ tape('testing deletion cases', function (tester) { const it = tester.test const trie = new CheckpointTrie() - it('should delete from a branch->branch-branch', async function (t) { - await trie.put(Buffer.from([11, 11, 11]), Buffer.from('first')) - await trie.put(Buffer.from([12, 22, 22]), Buffer.from('create the first branch')) - await trie.put(Buffer.from([12, 34, 44]), Buffer.from('create the last branch')) + it('should delete from a branch->branch-branch', function (t) { + trie.put(Buffer.from([11, 11, 11]), Buffer.from('first')) + trie.put(Buffer.from([12, 22, 22]), Buffer.from('create the first branch')) + trie.put(Buffer.from([12, 34, 44]), Buffer.from('create the last branch')) - await trie.del(Buffer.from([12, 22, 22])) - const val = await trie.get(Buffer.from([12, 22, 22])) + trie.del(Buffer.from([12, 22, 22])) + const val = trie.get(Buffer.from([12, 22, 22])) t.equal(null, val) t.end() }) - it('should delete from a branch->branch-extension', async function (t) { - await trie.put(Buffer.from([11, 11, 11]), Buffer.from('first')) - await trie.put(Buffer.from([12, 22, 22]), Buffer.from('create the first branch')) - await trie.put(Buffer.from([12, 33, 33]), Buffer.from('create the middle branch')) - await trie.put(Buffer.from([12, 34, 44]), Buffer.from('create the last branch')) + it('should delete from a branch->branch-extension', function (t) { + trie.put(Buffer.from([11, 11, 11]), Buffer.from('first')) + trie.put(Buffer.from([12, 22, 22]), Buffer.from('create the first branch')) + trie.put(Buffer.from([12, 33, 33]), Buffer.from('create the middle branch')) + trie.put(Buffer.from([12, 34, 44]), Buffer.from('create the last branch')) - await trie.del(Buffer.from([12, 22, 22])) - const val = await trie.get(Buffer.from([12, 22, 22])) + trie.del(Buffer.from([12, 22, 22])) + const val = trie.get(Buffer.from([12, 22, 22])) t.equal(null, val) t.end() }) - it('should delete from a extension->branch-extension', async function (t) { - await trie.put(Buffer.from([11, 11, 11]), Buffer.from('first')) - await trie.put(Buffer.from([12, 22, 22]), Buffer.from('create the first branch')) - await trie.put(Buffer.from([12, 33, 33]), Buffer.from('create the middle branch')) - await trie.put(Buffer.from([12, 34, 44]), Buffer.from('create the last branch')) + it('should delete from a extension->branch-extension', function (t) { + trie.put(Buffer.from([11, 11, 11]), Buffer.from('first')) + trie.put(Buffer.from([12, 22, 22]), Buffer.from('create the first branch')) + trie.put(Buffer.from([12, 33, 33]), Buffer.from('create the middle branch')) + trie.put(Buffer.from([12, 34, 44]), Buffer.from('create the last branch')) // delete the middle branch - await trie.del(Buffer.from([11, 11, 11])) - const val = await trie.get(Buffer.from([11, 11, 11])) + trie.del(Buffer.from([11, 11, 11])) + const val = trie.get(Buffer.from([11, 11, 11])) t.equal(null, val) t.end() }) - it('should delete from a extension->branch-branch', async function (t) { - await trie.put(Buffer.from([11, 11, 11]), Buffer.from('first')) - await trie.put(Buffer.from([12, 22, 22]), Buffer.from('create the first branch')) - await trie.put(Buffer.from([12, 33, 33]), Buffer.from('create the middle branch')) - await trie.put(Buffer.from([12, 34, 44]), Buffer.from('create the last branch')) + it('should delete from a extension->branch-branch', function (t) { + trie.put(Buffer.from([11, 11, 11]), Buffer.from('first')) + trie.put(Buffer.from([12, 22, 22]), Buffer.from('create the first branch')) + trie.put(Buffer.from([12, 33, 33]), Buffer.from('create the middle branch')) + trie.put(Buffer.from([12, 34, 44]), Buffer.from('create the last branch')) // delete the middle branch - await trie.del(Buffer.from([11, 11, 11])) - const val = await trie.get(Buffer.from([11, 11, 11])) + trie.del(Buffer.from([11, 11, 11])) + const val = trie.get(Buffer.from([11, 11, 11])) t.equal(null, val) t.end() }) @@ -232,11 +234,11 @@ tape('it should create the genesis state root from ethereum', function (tester) const genesisStateRoot = '2f4399b08efe68945c1cf90ffe85bbe3ce978959da753f9e649f034015b8817d' tester.equal(cppRlp, rlpAccount.toString('hex')) - it('shall match the root', async function (t) { - await trie4.put(g, rlpAccount) - await trie4.put(j, rlpAccount) - await trie4.put(v, rlpAccount) - await trie4.put(a, rlpAccount) + it('shall match the root', function (t) { + trie4.put(g, rlpAccount) + trie4.put(j, rlpAccount) + trie4.put(v, rlpAccount) + trie4.put(a, rlpAccount) t.equal(trie4.root.toString('hex'), genesisStateRoot) t.end() }) diff --git a/test/official.spec.ts b/test/official.spec.ts index 478f742..ac608cd 100644 --- a/test/official.spec.ts +++ b/test/official.spec.ts @@ -1,12 +1,12 @@ import * as tape from 'tape' import { CheckpointTrie } from '../src' -tape('offical tests', async function (t) { +tape('offical tests', function (t) { const jsonTests = require('./fixtures/trietest.json').tests const testNames = Object.keys(jsonTests) let trie = new CheckpointTrie() - for await (const testName of testNames) { + for (const testName of testNames) { let inputs = jsonTests[testName].in let expect = jsonTests[testName].root for (const input of inputs) { @@ -16,7 +16,7 @@ tape('offical tests', async function (t) { } else if (input[i] && typeof input[i] === 'string') { input[i] = Buffer.from(input[i]) } - await trie.put(Buffer.from(input[0]), input[1]) + trie.put(Buffer.from(input[0]), input[1]) } } t.equal('0x' + trie.root.toString('hex'), expect) @@ -25,15 +25,15 @@ tape('offical tests', async function (t) { t.end() }) -tape('offical tests any order', async function (t) { +tape('offical tests any order', function (t) { const jsonTests = require('./fixtures/trieanyorder.json').tests const testNames = Object.keys(jsonTests) let trie = new CheckpointTrie() - for await (const testName of testNames) { + for (const testName of testNames) { const test = jsonTests[testName] const keys = Object.keys(test.in) let key: any - for await (key of keys) { + for (key of keys) { let val = test.in[key] if (key.slice(0, 2) === '0x') { @@ -44,7 +44,7 @@ tape('offical tests any order', async function (t) { val = Buffer.from(val.slice(2), 'hex') } - await trie.put(Buffer.from(key), Buffer.from(val)) + trie.put(Buffer.from(key), Buffer.from(val)) } t.equal('0x' + trie.root.toString('hex'), test.root) trie = new CheckpointTrie() diff --git a/test/prioritizedTaskExecutor.spec.ts b/test/prioritizedTaskExecutor.spec.ts deleted file mode 100644 index 9d45509..0000000 --- a/test/prioritizedTaskExecutor.spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -import * as tape from 'tape' -import { PrioritizedTaskExecutor } from '../src/prioritizedTaskExecutor' - -const taskExecutor = new PrioritizedTaskExecutor(2) - -tape('prioritized task executor test', function (t) { - let tasks = [1, 2, 3, 4] - let callbacks = [] as any - let executionOrder = [] as any - tasks.forEach(function (task) { - taskExecutor.execute(task, function (cb: Function) { - executionOrder.push(task) - callbacks.push(cb) - }) - }) - - callbacks.forEach(function (callback: Function) { - callback() - }) - - let expectedExecutionOrder = [1, 2, 4, 3] - t.deepEqual(executionOrder, expectedExecutionOrder) - t.end() -}) diff --git a/test/proof.spec.ts b/test/proof.spec.ts index cc7a32d..1dc2db1 100644 --- a/test/proof.spec.ts +++ b/test/proof.spec.ts @@ -4,120 +4,114 @@ import { CheckpointTrie } from '../src' tape('simple merkle proofs generation and verification', function (tester) { const it = tester.test - it('create a merkle proof and verify it', async (t) => { + it('create a merkle proof and verify it', (t) => { const trie = new CheckpointTrie() - await trie.put(Buffer.from('key1aa'), Buffer.from('0123456789012345678901234567890123456789xx')) - await trie.put(Buffer.from('key2bb'), Buffer.from('aval2')) - await trie.put(Buffer.from('key3cc'), Buffer.from('aval3')) + trie.put(Buffer.from('key1aa'), Buffer.from('0123456789012345678901234567890123456789xx')) + trie.put(Buffer.from('key2bb'), Buffer.from('aval2')) + trie.put(Buffer.from('key3cc'), Buffer.from('aval3')) - let proof = await CheckpointTrie.prove(trie, Buffer.from('key2bb')) - let val = await CheckpointTrie.verifyProof(trie.root, Buffer.from('key2bb'), proof) + let proof = CheckpointTrie.prove(trie, Buffer.from('key2bb')) + let val = CheckpointTrie.verifyProof(trie.root, Buffer.from('key2bb'), proof) t.equal(val!.toString('utf8'), 'aval2') - proof = await CheckpointTrie.prove(trie, Buffer.from('key1aa')) - val = await CheckpointTrie.verifyProof(trie.root, Buffer.from('key1aa'), proof) + proof = CheckpointTrie.prove(trie, Buffer.from('key1aa')) + val = CheckpointTrie.verifyProof(trie.root, Buffer.from('key1aa'), proof) t.equal(val!.toString('utf8'), '0123456789012345678901234567890123456789xx') - proof = await CheckpointTrie.prove(trie, Buffer.from('key2bb')) - val = await CheckpointTrie.verifyProof(trie.root, Buffer.from('key2'), proof) + proof = CheckpointTrie.prove(trie, Buffer.from('key2bb')) + val = CheckpointTrie.verifyProof(trie.root, Buffer.from('key2'), proof) // In this case, the proof _happens_ to contain enough nodes to prove `key2` because // traversing into `key22` would touch all the same nodes as traversing into `key2` t.equal(val, null, 'Expected value at a random key to be null') let myKey = Buffer.from('anyrandomkey') - proof = await CheckpointTrie.prove(trie, myKey) - val = await CheckpointTrie.verifyProof(trie.root, myKey, proof) + proof = CheckpointTrie.prove(trie, myKey) + val = CheckpointTrie.verifyProof(trie.root, myKey, proof) t.equal(val, null, 'Expected value to be null') myKey = Buffer.from('anothergarbagekey') // should generate a valid proof of null - proof = await CheckpointTrie.prove(trie, myKey) + proof = CheckpointTrie.prove(trie, myKey) proof.push(Buffer.from('123456')) // extra nodes are just ignored - val = await CheckpointTrie.verifyProof(trie.root, myKey, proof) + val = CheckpointTrie.verifyProof(trie.root, myKey, proof) t.equal(val, null, 'Expected value to be null') - await trie.put(Buffer.from('another'), Buffer.from('3498h4riuhgwe')) + trie.put(Buffer.from('another'), Buffer.from('3498h4riuhgwe')) // to fail our proof we can request a proof for one key - proof = await CheckpointTrie.prove(trie, Buffer.from('another')) + proof = CheckpointTrie.prove(trie, Buffer.from('another')) // and use that proof on another key - const result = await CheckpointTrie.verifyProof(trie.root, Buffer.from('key1aa'), proof) + const result = CheckpointTrie.verifyProof(trie.root, Buffer.from('key1aa'), proof) t.equal(result, null) t.end() }) - it('create a merkle proof and verify it with a single long key', async (t) => { + it('create a merkle proof and verify it with a single long key', (t) => { const trie = new CheckpointTrie() - await trie.put(Buffer.from('key1aa'), Buffer.from('0123456789012345678901234567890123456789xx')) + trie.put(Buffer.from('key1aa'), Buffer.from('0123456789012345678901234567890123456789xx')) - const proof = await CheckpointTrie.prove(trie, Buffer.from('key1aa')) - const val = await CheckpointTrie.verifyProof(trie.root, Buffer.from('key1aa'), proof) + const proof = CheckpointTrie.prove(trie, Buffer.from('key1aa')) + const val = CheckpointTrie.verifyProof(trie.root, Buffer.from('key1aa'), proof) t.equal(val!.toString('utf8'), '0123456789012345678901234567890123456789xx') t.end() }) - it('create a merkle proof and verify it with a single short key', async (t) => { + it('create a merkle proof and verify it with a single short key', (t) => { const trie = new CheckpointTrie() - await trie.put(Buffer.from('key1aa'), Buffer.from('01234')) + trie.put(Buffer.from('key1aa'), Buffer.from('01234')) - const proof = await CheckpointTrie.prove(trie, Buffer.from('key1aa')) - const val = await CheckpointTrie.verifyProof(trie.root, Buffer.from('key1aa'), proof) + const proof = CheckpointTrie.prove(trie, Buffer.from('key1aa')) + const val = CheckpointTrie.verifyProof(trie.root, Buffer.from('key1aa'), proof) t.equal(val!.toString('utf8'), '01234') t.end() }) - it('create a merkle proof and verify it whit keys in the middle', async (t) => { + it('create a merkle proof and verify it whit keys in the middle', (t) => { const trie = new CheckpointTrie() - await trie.put( - Buffer.from('key1aa'), - Buffer.from('0123456789012345678901234567890123456789xxx'), - ) - await trie.put( - Buffer.from('key1'), - Buffer.from('0123456789012345678901234567890123456789Very_Long'), - ) - await trie.put(Buffer.from('key2bb'), Buffer.from('aval3')) - await trie.put(Buffer.from('key2'), Buffer.from('short')) - await trie.put(Buffer.from('key3cc'), Buffer.from('aval3')) - await trie.put(Buffer.from('key3'), Buffer.from('1234567890123456789012345678901')) - - let proof = await CheckpointTrie.prove(trie, Buffer.from('key1')) - let val = await CheckpointTrie.verifyProof(trie.root, Buffer.from('key1'), proof) + trie.put(Buffer.from('key1aa'), Buffer.from('0123456789012345678901234567890123456789xxx')) + trie.put(Buffer.from('key1'), Buffer.from('0123456789012345678901234567890123456789Very_Long')) + trie.put(Buffer.from('key2bb'), Buffer.from('aval3')) + trie.put(Buffer.from('key2'), Buffer.from('short')) + trie.put(Buffer.from('key3cc'), Buffer.from('aval3')) + trie.put(Buffer.from('key3'), Buffer.from('1234567890123456789012345678901')) + + let proof = CheckpointTrie.prove(trie, Buffer.from('key1')) + let val = CheckpointTrie.verifyProof(trie.root, Buffer.from('key1'), proof) t.equal(val!.toString('utf8'), '0123456789012345678901234567890123456789Very_Long') - proof = await CheckpointTrie.prove(trie, Buffer.from('key2')) - val = await CheckpointTrie.verifyProof(trie.root, Buffer.from('key2'), proof) + proof = CheckpointTrie.prove(trie, Buffer.from('key2')) + val = CheckpointTrie.verifyProof(trie.root, Buffer.from('key2'), proof) t.equal(val!.toString('utf8'), 'short') - proof = await CheckpointTrie.prove(trie, Buffer.from('key3')) - val = await CheckpointTrie.verifyProof(trie.root, Buffer.from('key3'), proof) + proof = CheckpointTrie.prove(trie, Buffer.from('key3')) + val = CheckpointTrie.verifyProof(trie.root, Buffer.from('key3'), proof) t.equal(val!.toString('utf8'), '1234567890123456789012345678901') t.end() }) - it('should succeed with a simple embedded extension-branch', async (t) => { + it('should succeed with a simple embedded extension-branch', (t) => { const trie = new CheckpointTrie() - await trie.put(Buffer.from('a'), Buffer.from('a')) - await trie.put(Buffer.from('b'), Buffer.from('b')) - await trie.put(Buffer.from('c'), Buffer.from('c')) + trie.put(Buffer.from('a'), Buffer.from('a')) + trie.put(Buffer.from('b'), Buffer.from('b')) + trie.put(Buffer.from('c'), Buffer.from('c')) - let proof = await CheckpointTrie.prove(trie, Buffer.from('a')) - let val = await CheckpointTrie.verifyProof(trie.root, Buffer.from('a'), proof) + let proof = CheckpointTrie.prove(trie, Buffer.from('a')) + let val = CheckpointTrie.verifyProof(trie.root, Buffer.from('a'), proof) t.equal(val!.toString('utf8'), 'a') - proof = await CheckpointTrie.prove(trie, Buffer.from('b')) - val = await CheckpointTrie.verifyProof(trie.root, Buffer.from('b'), proof) + proof = CheckpointTrie.prove(trie, Buffer.from('b')) + val = CheckpointTrie.verifyProof(trie.root, Buffer.from('b'), proof) t.equal(val!.toString('utf8'), 'b') - proof = await CheckpointTrie.prove(trie, Buffer.from('c')) - val = await CheckpointTrie.verifyProof(trie.root, Buffer.from('c'), proof) + proof = CheckpointTrie.prove(trie, Buffer.from('c')) + val = CheckpointTrie.verifyProof(trie.root, Buffer.from('c'), proof) t.equal(val!.toString('utf8'), 'c') t.end() diff --git a/test/scratch.spec.ts b/test/scratch.spec.ts index 2ef8527..088e255 100644 --- a/test/scratch.spec.ts +++ b/test/scratch.spec.ts @@ -11,34 +11,34 @@ tape('ScratchDB', (t) => { const k2 = Buffer.from('bar') const v2 = Buffer.from('baz') - t.test('should fail to get non-existent value', async (st) => { - const res = await scratch.get(k) + t.test('should fail to get non-existent value', (st) => { + const res = scratch.get(k) st.notOk(res) st.end() }) - t.test('puts value to scratch', async (st) => { - await scratch.put(k, v) - const res = await scratch.get(k) + t.test('puts value to scratch', (st) => { + scratch.put(k, v) + const res = scratch.get(k) st.ok(v.equals(res!)) st.end() }) - t.test('should not have put value to upstream', async (st) => { - const res = await upstream.get(k) + t.test('should not have put value to upstream', (st) => { + const res = upstream.get(k) st.notOk(res) st.end() }) - t.test('should put value directly to upstream', async (st) => { - await upstream.put(k2, v2) - const res = await upstream.get(k2) + t.test('should put value directly to upstream', (st) => { + upstream.put(k2, v2) + const res = upstream.get(k2) st.ok(v2.equals(res!)) st.end() }) - t.test('scratch should get value from upstream', async (st) => { - const res = await scratch.get(k2) + t.test('scratch should get value from upstream', (st) => { + const res = scratch.get(k2) st.ok(v2.equals(res!)) st.end() }) diff --git a/test/secure.spec.ts b/test/secure.spec.ts index 841575c..8d08855 100644 --- a/test/secure.spec.ts +++ b/test/secure.spec.ts @@ -6,27 +6,27 @@ tape('SecureTrie', function (t) { const k = Buffer.from('foo') const v = Buffer.from('bar') - t.test('put and get value', async function (st) { - await trie.put(k, v) - const res = await trie.get(k) + t.test('put and get value', function (st) { + trie.put(k, v) + const res = trie.get(k) st.ok(v.equals(res!)) st.end() }) - t.test('copy trie', async function (st) { + t.test('copy trie', function (st) { const t = trie.copy() - const res = await t.get(k) + const res = t.get(k) st.ok(v.equals(res!)) st.end() }) tape('SecureTrie proof', function (t) { - t.test('create a merkle proof and verify it with a single short key', async function (st) { + t.test('create a merkle proof and verify it with a single short key', function (st) { const trie = new SecureTrie() - await trie.put(Buffer.from('key1aa'), Buffer.from('01234')) + trie.put(Buffer.from('key1aa'), Buffer.from('01234')) - const proof = await SecureTrie.prove(trie, Buffer.from('key1aa')) - const val = await SecureTrie.verifyProof(trie.root, Buffer.from('key1aa'), proof) + const proof = SecureTrie.prove(trie, Buffer.from('key1aa')) + const val = SecureTrie.verifyProof(trie.root, Buffer.from('key1aa'), proof) st.equal(val!.toString('utf8'), '01234') st.end() }) @@ -36,32 +36,32 @@ tape('SecureTrie', function (t) { let trie = new SecureTrie() const jsonTests = require('./fixtures/trietest_secureTrie.json').tests - it.test('empty values', async function (t) { - for await (const row of jsonTests.emptyValues.in) { + it.test('empty values', function (t) { + for (const row of jsonTests.emptyValues.in) { const val = row[1] ? Buffer.from(row[1]) : ((null as unknown) as Buffer) - await trie.put(Buffer.from(row[0]), val) + trie.put(Buffer.from(row[0]), val) } t.equal('0x' + trie.root.toString('hex'), jsonTests.emptyValues.root) t.end() }) - it.test('branchingTests', async function (t) { + it.test('branchingTests', function (t) { trie = new SecureTrie() - for await (const row of jsonTests.branchingTests.in) { + for (const row of jsonTests.branchingTests.in) { const val = row[1] ? Buffer.from(row[1]) : ((null as unknown) as Buffer) - await trie.put(Buffer.from(row[0]), val) + trie.put(Buffer.from(row[0]), val) } t.equal('0x' + trie.root.toString('hex'), jsonTests.branchingTests.root) t.end() }) - it.test('jeff', async function (t) { - for await (const row of jsonTests.jeff.in) { + it.test('jeff', function (t) { + for (const row of jsonTests.jeff.in) { let val = row[1] if (val) { val = Buffer.from(row[1].slice(2), 'hex') } - await trie.put(Buffer.from(row[0].slice(2), 'hex'), val) + trie.put(Buffer.from(row[0].slice(2), 'hex'), val) } t.equal('0x' + trie.root.toString('hex'), jsonTests.jeff.root.toString('hex')) t.end() @@ -110,17 +110,17 @@ const g = Buffer.from( ) const gk = Buffer.from('095e7baea6a6c7c4c2dfeb977efac326af552d87', 'hex') -tape('secure tests should not crash', async function (t) { - await trie.put(ak, a) - await trie.put(bk, b) - await trie.put(ck, c) +tape('secure tests should not crash', function (t) { + trie.put(ak, a) + trie.put(bk, b) + trie.put(ck, c) trie.checkpoint() trie.checkpoint() - await trie.commit() - await trie.put(dk, d) - await trie.put(ek, e) - await trie.put(fk, f) - await trie.commit() - await trie.put(gk, g) + trie.commit() + trie.put(dk, d) + trie.put(ek, e) + trie.put(fk, f) + trie.commit() + trie.put(gk, g) t.end() }) diff --git a/test/stream.spec.ts b/test/stream.spec.ts deleted file mode 100644 index ce229d7..0000000 --- a/test/stream.spec.ts +++ /dev/null @@ -1,186 +0,0 @@ -import * as tape from 'tape' -import { CheckpointTrie } from '../src' -import { BatchDBOp } from '../src/db' - -tape('kv stream test', function (tester) { - const it = tester.test - const trie = new CheckpointTrie() - const ops = [ - { - type: 'del', - key: Buffer.from('father'), - }, - { - type: 'put', - key: Buffer.from('name'), - value: Buffer.from('Yuri Irsenovich Kim'), - }, - { - type: 'put', - key: Buffer.from('dob'), - value: Buffer.from('16 February 1941'), - }, - { - type: 'put', - key: Buffer.from('spouse'), - value: Buffer.from('Kim Young-sook'), - }, - { - type: 'put', - key: Buffer.from('occupation'), - value: Buffer.from('Clown'), - }, - { - type: 'put', - key: Buffer.from('nameads'), - value: Buffer.from('Yuri Irsenovich Kim'), - }, - { - type: 'put', - key: Buffer.from('namfde'), - value: Buffer.from('Yuri Irsenovich Kim'), - }, - { - type: 'put', - key: Buffer.from('namsse'), - value: Buffer.from('Yuri Irsenovich Kim'), - }, - { - type: 'put', - key: Buffer.from('dofab'), - value: Buffer.from('16 February 1941'), - }, - { - type: 'put', - key: Buffer.from('spoudse'), - value: Buffer.from('Kim Young-sook'), - }, - { - type: 'put', - key: Buffer.from('occupdsation'), - value: Buffer.from('Clown'), - }, - { - type: 'put', - key: Buffer.from('dozzzb'), - value: Buffer.from('16 February 1941'), - }, - { - type: 'put', - key: Buffer.from('spouszze'), - value: Buffer.from('Kim Young-sook'), - }, - { - type: 'put', - key: Buffer.from('occupatdfion'), - value: Buffer.from('Clown'), - }, - { - type: 'put', - key: Buffer.from('dssob'), - value: Buffer.from('16 February 1941'), - }, - { - type: 'put', - key: Buffer.from('spossuse'), - value: Buffer.from('Kim Young-sook'), - }, - { - type: 'put', - key: Buffer.from('occupssation'), - value: Buffer.from('Clown'), - }, - ] as BatchDBOp[] - - let valObj = {} as any - for (let op of ops) { - if (op.type === 'put') { - valObj[op.key.toString()] = op.value.toString() - } - } - - it('should populate trie', async function (t) { - await trie.batch(ops) - t.end() - }) - - it('should fetch all of the nodes', function (t) { - const stream = trie.createReadStream() - stream.on('data', (d: any) => { - const key = d.key.toString() - const value = d.value.toString() - t.equal(valObj[key], value) - delete valObj[key] - }) - stream.on('end', () => { - let keys = Object.keys(valObj) - t.equal(keys.length, 0) - t.end() - }) - }) -}) - -tape('db stream test', function (tester) { - const it = tester.test - const trie = new CheckpointTrie() - const ops = [ - { - type: 'put', - key: Buffer.from('color'), - value: Buffer.from('purple'), - }, - { - type: 'put', - key: Buffer.from('food'), - value: Buffer.from('sushi'), - }, - { - type: 'put', - key: Buffer.from('fight'), - value: Buffer.from('fire'), - }, - { - type: 'put', - key: Buffer.from('colo'), - value: Buffer.from('trolo'), - }, - { - type: 'put', - key: Buffer.from('color'), - value: Buffer.from('blue'), - }, - { - type: 'put', - key: Buffer.from('color'), - value: Buffer.from('pink'), - }, - ] as BatchDBOp[] - - const expectedNodes = { - '3c38d9aa6ad288c8e27da701e17fe99a5b67c8b12fd0469651c80494d36bc4c1': true, - d5f61e1ff2b918d1c2a2c4b1732a3c68bd7e3fd64f35019f2f084896d4546298: true, - e64329dadee2fb8a113b4c88cfe973aeaa9b523d4dc8510b84ca23f9d5bfbd90: true, - c916d458bfb5f27603c5bd93b00f022266712514a59cde749f19220daffc743f: true, - '2386bfb0de9cf93902a110f5ab07b917ffc0b9ea599cb7f4f8bb6fd1123c866c': true, - } as any - - it('should populate trie', async function (t) { - trie.checkpoint() - await trie.batch(ops) - t.end() - }) - - it('should only fetch nodes in the current trie', function (t) { - const stream = trie._createScratchReadStream() - stream.on('data', (d: any) => { - const key = d.key.toString('hex') - t.ok(!!expectedNodes[key]) - delete expectedNodes[key] - }) - stream.on('end', () => { - let keys = Object.keys(expectedNodes) - t.equal(keys.length, 0) - t.end() - }) - }) -})