Skip to content
This repository has been archived by the owner on Jan 19, 2021. It is now read-only.

Commit

Permalink
Fix checkpoint copy, add tests for checkpoint and secure copy
Browse files Browse the repository at this point in the history
Signed-off-by: Sina Mahmoodi <[email protected]>
  • Loading branch information
s1na committed Jan 22, 2019
1 parent a4c7f54 commit 4ea8d58
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 44 deletions.
72 changes: 37 additions & 35 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,9 +291,10 @@ Performs a batch operation on db.

## copy

[src/db.js:79-81][33]
[src/db.js:80-82][33]

Returns a copy of DB.
Returns a copy of the DB instance, with a reference
to the **same** underlying leveldb instance.

## get

Expand Down Expand Up @@ -363,14 +364,15 @@ parent checkpoint as current.

## copy

[src/checkpointTrie.js:104-110][40]
[src/checkpointTrie.js:105-114][40]

Returns a copy of the underlying trie with the interface
of CheckpointTrie.
of CheckpointTrie. If during a checkpoint, the copy will
contain the checkpointing metadata (incl. reference to the same scratch).

[1]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/defcc7ebd7744d72765b157d50f8d21caa663c9a/src/secure.js#L12-L44 "Source code on GitHub"
[1]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/a4c7f5423da6a9d23ff0aa886c2fd560dac05b7d/src/secure.js#L12-L44 "Source code on GitHub"

[2]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/defcc7ebd7744d72765b157d50f8d21caa663c9a/src/baseTrie.js#L25-L701 "Source code on GitHub"
[2]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/a4c7f5423da6a9d23ff0aa886c2fd560dac05b7d/src/baseTrie.js#L25-L701 "Source code on GitHub"

[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object

Expand All @@ -380,70 +382,70 @@ of CheckpointTrie.

[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String

[7]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/defcc7ebd7744d72765b157d50f8d21caa663c9a/src/baseTrie.js#L59-L71 "Source code on GitHub"
[7]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/a4c7f5423da6a9d23ff0aa886c2fd560dac05b7d/src/baseTrie.js#L59-L71 "Source code on GitHub"

[8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function

[9]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/defcc7ebd7744d72765b157d50f8d21caa663c9a/src/baseTrie.js#L81-L105 "Source code on GitHub"
[9]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/a4c7f5423da6a9d23ff0aa886c2fd560dac05b7d/src/baseTrie.js#L81-L105 "Source code on GitHub"

[10]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/defcc7ebd7744d72765b157d50f8d21caa663c9a/src/baseTrie.js#L114-L130 "Source code on GitHub"
[10]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/a4c7f5423da6a9d23ff0aa886c2fd560dac05b7d/src/baseTrie.js#L114-L130 "Source code on GitHub"

[11]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/defcc7ebd7744d72765b157d50f8d21caa663c9a/src/baseTrie.js#L171-L217 "Source code on GitHub"
[11]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/a4c7f5423da6a9d23ff0aa886c2fd560dac05b7d/src/baseTrie.js#L171-L217 "Source code on GitHub"

[12]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/defcc7ebd7744d72765b157d50f8d21caa663c9a/src/baseTrie.js#L649-L651 "Source code on GitHub"
[12]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/a4c7f5423da6a9d23ff0aa886c2fd560dac05b7d/src/baseTrie.js#L649-L651 "Source code on GitHub"

[13]: https://nodejs.org/api/stream.html#stream_class_stream_readable

[14]: https://nodejs.org/dist/latest-v5.x/docs/api/stream.html#stream_class_stream_readable

[15]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/defcc7ebd7744d72765b157d50f8d21caa663c9a/src/baseTrie.js#L676-L686 "Source code on GitHub"
[15]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/a4c7f5423da6a9d23ff0aa886c2fd560dac05b7d/src/baseTrie.js#L676-L686 "Source code on GitHub"

[16]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array

[17]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/defcc7ebd7744d72765b157d50f8d21caa663c9a/src/baseTrie.js#L695-L700 "Source code on GitHub"
[17]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/a4c7f5423da6a9d23ff0aa886c2fd560dac05b7d/src/baseTrie.js#L695-L700 "Source code on GitHub"

[18]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/defcc7ebd7744d72765b157d50f8d21caa663c9a/src/proof.js#L12-L29 "Source code on GitHub"
[18]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/a4c7f5423da6a9d23ff0aa886c2fd560dac05b7d/src/proof.js#L12-L29 "Source code on GitHub"

[19]: #trie

[20]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/defcc7ebd7744d72765b157d50f8d21caa663c9a/src/proof.js#L39-L100 "Source code on GitHub"
[20]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/a4c7f5423da6a9d23ff0aa886c2fd560dac05b7d/src/proof.js#L39-L100 "Source code on GitHub"

[21]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/defcc7ebd7744d72765b157d50f8d21caa663c9a/src/util/hex.js#L7-L22 "Source code on GitHub"
[21]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/a4c7f5423da6a9d23ff0aa886c2fd560dac05b7d/src/util/hex.js#L7-L22 "Source code on GitHub"

[22]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/defcc7ebd7744d72765b157d50f8d21caa663c9a/src/util/async.js#L38-L54 "Source code on GitHub"
[22]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/a4c7f5423da6a9d23ff0aa886c2fd560dac05b7d/src/util/async.js#L38-L54 "Source code on GitHub"

[23]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/defcc7ebd7744d72765b157d50f8d21caa663c9a/src/util/nibbles.js#L56-L59 "Source code on GitHub"
[23]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/a4c7f5423da6a9d23ff0aa886c2fd560dac05b7d/src/util/nibbles.js#L56-L59 "Source code on GitHub"

[24]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/defcc7ebd7744d72765b157d50f8d21caa663c9a/src/util/async.js#L3-L6 "Source code on GitHub"
[24]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/a4c7f5423da6a9d23ff0aa886c2fd560dac05b7d/src/util/async.js#L3-L6 "Source code on GitHub"

[25]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/defcc7ebd7744d72765b157d50f8d21caa663c9a/src/db.js#L3-L3 "Source code on GitHub"
[25]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/a4c7f5423da6a9d23ff0aa886c2fd560dac05b7d/src/db.js#L3-L3 "Source code on GitHub"

[26]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/defcc7ebd7744d72765b157d50f8d21caa663c9a/src/scratch.js#L4-L4 "Source code on GitHub"
[26]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/a4c7f5423da6a9d23ff0aa886c2fd560dac05b7d/src/scratch.js#L4-L4 "Source code on GitHub"

[27]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/defcc7ebd7744d72765b157d50f8d21caa663c9a/src/node/index.js#L12-L31 "Source code on GitHub"
[27]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/a4c7f5423da6a9d23ff0aa886c2fd560dac05b7d/src/node/index.js#L12-L31 "Source code on GitHub"

[28]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/defcc7ebd7744d72765b157d50f8d21caa663c9a/src/db.js#L15-L17 "Source code on GitHub"
[28]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/a4c7f5423da6a9d23ff0aa886c2fd560dac05b7d/src/db.js#L15-L17 "Source code on GitHub"

[29]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/defcc7ebd7744d72765b157d50f8d21caa663c9a/src/db.js#L26-L36 "Source code on GitHub"
[29]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/a4c7f5423da6a9d23ff0aa886c2fd560dac05b7d/src/db.js#L26-L36 "Source code on GitHub"

[30]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/defcc7ebd7744d72765b157d50f8d21caa663c9a/src/db.js#L45-L50 "Source code on GitHub"
[30]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/a4c7f5423da6a9d23ff0aa886c2fd560dac05b7d/src/db.js#L45-L50 "Source code on GitHub"

[31]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/defcc7ebd7744d72765b157d50f8d21caa663c9a/src/db.js#L58-L62 "Source code on GitHub"
[31]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/a4c7f5423da6a9d23ff0aa886c2fd560dac05b7d/src/db.js#L58-L62 "Source code on GitHub"

[32]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/defcc7ebd7744d72765b157d50f8d21caa663c9a/src/db.js#L70-L74 "Source code on GitHub"
[32]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/a4c7f5423da6a9d23ff0aa886c2fd560dac05b7d/src/db.js#L70-L74 "Source code on GitHub"

[33]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/defcc7ebd7744d72765b157d50f8d21caa663c9a/src/db.js#L79-L81 "Source code on GitHub"
[33]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/a4c7f5423da6a9d23ff0aa886c2fd560dac05b7d/src/db.js#L80-L82 "Source code on GitHub"

[34]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/defcc7ebd7744d72765b157d50f8d21caa663c9a/src/scratch.js#L22-L35 "Source code on GitHub"
[34]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/a4c7f5423da6a9d23ff0aa886c2fd560dac05b7d/src/scratch.js#L22-L35 "Source code on GitHub"

[35]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/defcc7ebd7744d72765b157d50f8d21caa663c9a/src/checkpointTrie.js#L31-L33 "Source code on GitHub"
[35]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/a4c7f5423da6a9d23ff0aa886c2fd560dac05b7d/src/checkpointTrie.js#L31-L33 "Source code on GitHub"

[36]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/defcc7ebd7744d72765b157d50f8d21caa663c9a/src/secure.js#L31-L38 "Source code on GitHub"
[36]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/a4c7f5423da6a9d23ff0aa886c2fd560dac05b7d/src/secure.js#L31-L38 "Source code on GitHub"

[37]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/defcc7ebd7744d72765b157d50f8d21caa663c9a/src/checkpointTrie.js#L42-L50 "Source code on GitHub"
[37]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/a4c7f5423da6a9d23ff0aa886c2fd560dac05b7d/src/checkpointTrie.js#L42-L50 "Source code on GitHub"

[38]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/defcc7ebd7744d72765b157d50f8d21caa663c9a/src/checkpointTrie.js#L59-L74 "Source code on GitHub"
[38]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/a4c7f5423da6a9d23ff0aa886c2fd560dac05b7d/src/checkpointTrie.js#L59-L74 "Source code on GitHub"

[39]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/defcc7ebd7744d72765b157d50f8d21caa663c9a/src/checkpointTrie.js#L83-L97 "Source code on GitHub"
[39]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/a4c7f5423da6a9d23ff0aa886c2fd560dac05b7d/src/checkpointTrie.js#L83-L97 "Source code on GitHub"

[40]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/defcc7ebd7744d72765b157d50f8d21caa663c9a/src/checkpointTrie.js#L104-L110 "Source code on GitHub"
[40]: https://[email protected]/:ethereumjs/merkle-patricia-tree/blob/a4c7f5423da6a9d23ff0aa886c2fd560dac05b7d/src/checkpointTrie.js#L105-L114 "Source code on GitHub"
10 changes: 7 additions & 3 deletions src/checkpointTrie.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,18 @@ module.exports = class CheckpointTrie extends BaseTrie {

/**
* Returns a copy of the underlying trie with the interface
* of CheckpointTrie.
* of CheckpointTrie. If during a checkpoint, the copy will
* contain the checkpointing metadata (incl. reference to the same scratch).
* @method copy
*/
copy () {
const db = this._mainDB.copy()
const trie = new CheckpointTrie(db, this.root)
trie._scratch = this._scratch
trie._checkpoints = this._checkpoints.slice()
if (this.isCheckpoint) {
trie._checkpoints = this._checkpoints.slice()
trie._scratch = this._scratch.copy()
trie.db = trie._scratch
}
return trie
}

Expand Down
3 changes: 2 additions & 1 deletion src/db.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ module.exports = class DB {
}

/**
* Returns a copy of DB.
* Returns a copy of the DB instance, with a reference
* to the **same** underlying leveldb instance.
*/
copy () {
return new DB(this._leveldb)
Expand Down
10 changes: 8 additions & 2 deletions src/scratch.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ const ENCODING_OPTS = { keyEncoding: 'binary', valueEncoding: 'binary' }
module.exports = class ScratchDB extends DB {
constructor (upstreamDB) {
super()
this._upstream = upstreamDB._leveldb
this._upstream = upstreamDB
}

/**
* Similar to `DB.get`, but first searches in-memory
* scratch DB, if key not found, searches upstream DB.
*/
get (key, cb) {
const getDBs = this._upstream ? [this._leveldb, this._upstream] : [this._leveldb]
const getDBs = this._upstream._leveldb ? [this._leveldb, this._upstream._leveldb] : [this._leveldb]
const dbGet = (db, cb2) => {
db.get(key, ENCODING_OPTS, (err, v) => {
if (err || !v) {
Expand All @@ -33,4 +33,10 @@ module.exports = class ScratchDB extends DB {

asyncFirstSeries(getDBs, dbGet, cb)
}

copy () {
const scratch = new ScratchDB(this._upstream)
scratch._leveldb = this._leveldb
return scratch
}
}
30 changes: 28 additions & 2 deletions test/checkpoint.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
const tape = require('tape')
const Trie = require('../src/index')
const Trie = require('../src/checkpointTrie')

tape('testing checkpoints', function (tester) {
let trie, preRoot, postRoot
let trie, preRoot, postRoot, trieCopy
const it = tester.test

it('setup', function (t) {
Expand All @@ -15,6 +15,16 @@ tape('testing checkpoints', function (tester) {
})
})

it('should copy trie and get value before checkpoint', function (t) {
trieCopy = trie.copy()
t.equal(trieCopy.root.toString('hex'), preRoot)
trieCopy.get('do', function (err, res) {
t.error(err)
t.ok(Buffer.from('verb').equals(res))
t.end()
})
})

it('should create a checkpoint', function (t) {
trie.checkpoint()
t.end()
Expand Down Expand Up @@ -45,6 +55,22 @@ tape('testing checkpoints', function (tester) {
})
})

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)
trieCopy.get('do', function (err, res) {
t.error(err)
t.ok(Buffer.from('verb').equals(res))
trieCopy.get('love', function (err, res) {
t.error(err)
t.ok(Buffer.from('emotion').equals(res))
t.end()
})
})
})

it('should revert to the orginal root', function (t) {
t.equal(trie.isCheckpoint, true)
trie.revert(function () {
Expand Down
28 changes: 27 additions & 1 deletion test/secure.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,36 @@ const Trie = require('../src/secure.js')
const async = require('async')
const tape = require('tape')

var trie = new Trie()

tape('SecureTrie', function (t) {
const trie = new Trie()
const k = Buffer.from('foo')
const v = Buffer.from('bar')

t.test('put and get value', function (st) {
trie.put(k, v, function () {
trie.get(k, function (err, res) {
st.error(err)
st.ok(v.equals(res))
st.end()
})
})
})

t.test('copy trie', function (st) {
const t = trie.copy()
t.get(k, function (err, res) {
st.error(err)
st.ok(v.equals(res))
st.end()
})
})
})

tape('secure tests', function (it) {
let trie = new Trie()
const jsonTests = require('./fixture/trietest_secureTrie.json').tests

it.test('empty values', function (t) {
async.eachSeries(jsonTests.emptyValues.in, function (row, cb) {
trie.put(new Buffer(row[0]), row[1], cb)
Expand Down

0 comments on commit 4ea8d58

Please sign in to comment.