diff --git a/CHANGELOG.md b/CHANGELOG.md index d99a82a..91720c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,10 @@ See the [docs](https://github.com/ethereumjs/merkle-patricia-tree/tree/master/do `getRaw`, `putRaw` and `delRaw` were deprecated in `v3.0.0` and have been removed from this release. Instead, please use `trie.db.get`, `trie.db.put`, and `trie.db.del`. If using a `SecureTrie` or `CheckpointTrie`, use `trie._maindb` to override the checkpointing mechanism and interact directly with the db. +#### SecureTrie.copy + +`SecureTrie.copy` now includes checkpoint metadata by default. To maintain original behavior of _not_ copying checkpoint state, pass `false` to param `includeCheckpoints`. + ### Changed - Convert trieNode to ES6 class ([#71](https://github.com/ethereumjs/merkle-patricia-tree/pull/71)) @@ -42,6 +46,7 @@ See the [docs](https://github.com/ethereumjs/merkle-patricia-tree/tree/master/do - Use `Nibbles` type for `number[]` ([#115](https://github.com/ethereumjs/merkle-patricia-tree/pull/115)) - Upgrade ethereumjs-util to 7.0.0 / Upgrade level-mem to 5.0.1 ([#116](https://github.com/ethereumjs/merkle-patricia-tree/pull/116)) - Create dual ES5 and ES2017 builds ([#117](https://github.com/ethereumjs/merkle-patricia-tree/pull/117)) +- Include checkpoints by default in SecureTrie.copy ([#119](https://github.com/ethereumjs/merkle-patricia-tree/pull/119)) ### Added diff --git a/src/checkpointTrie.ts b/src/checkpointTrie.ts index 5ee40e4..2a63f87 100644 --- a/src/checkpointTrie.ts +++ b/src/checkpointTrie.ts @@ -81,13 +81,10 @@ export class CheckpointTrie extends BaseTrie { } /** - * Returns a copy of the underlying trie with the interface - * of CheckpointTrie. If during a checkpoint, the copy will - * contain the checkpointing metadata (incl. reference to the same scratch). - * @param {boolean} includeCheckpoints - If true and during a checkpoint, the copy will - * contain the checkpointing metadata and will use the same scratch as underlying db. + * Returns a copy of the underlying trie with the interface of CheckpointTrie. + * @param {boolean} includeCheckpoints - If true and during a checkpoint, the copy will contain the checkpointing metadata and will use the same scratch as underlying db. */ - copy(includeCheckpoints: boolean = true): CheckpointTrie { + copy(includeCheckpoints = true): CheckpointTrie { const db = this._mainDB.copy() const trie = new CheckpointTrie(db._leveldb, this.root) if (includeCheckpoints && this.isCheckpoint) { diff --git a/src/secure.ts b/src/secure.ts index 5a47600..cfc4fdc 100644 --- a/src/secure.ts +++ b/src/secure.ts @@ -24,8 +24,12 @@ export class SecureTrie extends CheckpointTrie { return super.verifyProof(rootHash, hash, proof) } - copy(): SecureTrie { - const trie = super.copy(false) + /** + * Returns a copy of the underlying trie with the interface of SecureTrie. + * @param {boolean} includeCheckpoints - If true and during a checkpoint, the copy will contain the checkpointing metadata and will use the same scratch as underlying db. + */ + copy(includeCheckpoints = true): SecureTrie { + const trie = super.copy(includeCheckpoints) const db = trie.db.copy() return new SecureTrie(db._leveldb, this.root) } diff --git a/test/secure.spec.ts b/test/secure.spec.ts index 4f7bb0b..448612d 100644 --- a/test/secure.spec.ts +++ b/test/secure.spec.ts @@ -124,3 +124,29 @@ tape('secure tests should not crash', async function (t) { await trie.put(gk, g) t.end() }) + +tape('SecureTrie.copy', function (it) { + it.test('created copy includes values added after checkpoint', async function (t) { + const trie = new SecureTrie() + + await trie.put(Buffer.from('key1'), Buffer.from('value1')) + trie.checkpoint() + await trie.put(Buffer.from('key2'), Buffer.from('value2')) + const trieCopy = trie.copy() + const value = await trieCopy.get(Buffer.from('key2')) + t.equal(value.toString(), 'value2') + t.end() + }) + + it.test('created copy includes values added before checkpoint', async function (t) { + const trie = new SecureTrie() + + await trie.put(Buffer.from('key1'), Buffer.from('value1')) + trie.checkpoint() + await trie.put(Buffer.from('key2'), Buffer.from('value2')) + const trieCopy = trie.copy() + const value = await trieCopy.get(Buffer.from('key1')) + t.equal(value.toString(), 'value1') + t.end() + }) +})