Skip to content
This repository has been archived by the owner on Apr 6, 2020. It is now read-only.

Commit

Permalink
Added support for setting network and hardfork-specific validation
Browse files Browse the repository at this point in the history
  • Loading branch information
vpulim committed Aug 4, 2018
1 parent 3a94498 commit 2e1671d
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 16 deletions.
28 changes: 22 additions & 6 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const semaphore = require('semaphore')
const levelup = require('levelup')
const memdown = require('memdown')
const Block = require('ethereumjs-block')
const Common = require('ethereumjs-common')
const ethUtil = require('ethereumjs-util')
const Ethash = require('ethashjs')
const Buffer = require('safe-buffer').Buffer
Expand Down Expand Up @@ -36,6 +37,17 @@ function Blockchain (opts) {
opts = opts || {}
const self = this

if (opts.common) {
if (opts.chain) {
throw new Error('Instantiation with both opts.common and opts.chain parameter not allowed!')
}
this._common = opts.common
} else {
let chain = opts.chain ? opts.chain : 'mainnet'
let hardfork = opts.hardfork ? opts.hardfork : null
this._common = new Common(chain, hardfork)
}

// backwards compatibilty with older constructor interfaces
if (opts.constructor.name === 'LevelUP') {
opts = { db: opts }
Expand Down Expand Up @@ -144,7 +156,7 @@ Blockchain.prototype._init = function (cb) {
*/
Blockchain.prototype._setCanonicalGenesisBlock = function (cb) {
const self = this
var genesisBlock = new Block()
var genesisBlock = new Block(null, {common: self._common})
genesisBlock.setGenesisParams()
self._putBlockOrHeader(genesisBlock, cb, true)
}
Expand Down Expand Up @@ -311,7 +323,7 @@ Blockchain.prototype.putHeader = function (header, cb) {
Blockchain.prototype._putBlockOrHeader = function (item, cb, isGenesis) {
const self = this
var isHeader = item instanceof Block.Header
var block = isHeader ? new Block([item.raw, [], []]) : item
var block = isHeader ? new Block([item.raw, [], []], {common: item._common}) : item
var header = block.header
var hash = block.hash()
var number = new BN(header.number)
Expand All @@ -320,7 +332,11 @@ Blockchain.prototype._putBlockOrHeader = function (item, cb, isGenesis) {
var dbOps = []

if (block.constructor !== Block) {
block = new Block(block)
block = new Block(block, {common: self._common})
}

if (block._common.chainId() !== self._common.chainId()) {
return cb(new Error('Chain mismatch while trying to put block or header'))
}

async.series([
Expand Down Expand Up @@ -514,7 +530,7 @@ Blockchain.prototype._getBlock = function (blockTag, cb) {
}
}, (err, parts) => {
if (err) return cb(err)
cb(null, new Block([parts.header].concat(parts.body)))
cb(null, new Block([parts.header].concat(parts.body), {common: self._common}))
})
}
}
Expand Down Expand Up @@ -1025,15 +1041,15 @@ Blockchain.prototype._getHeader = function (hash, number, cb) {
var key = headerKey(number, hash)
var encodedHeader = self._cache.header.get(key)
if (encodedHeader) {
return cb(null, new Block.Header(rlp.decode(encodedHeader)))
return cb(null, new Block.Header(rlp.decode(encodedHeader), {common: self._common}))
}
self.db.get(key, {
keyEncoding: 'binary',
valueEncoding: 'binary'
}, (err, encodedHeader) => {
if (err) return cb(err)
self._cache.header.set(key, encodedHeader)
cb(null, new Block.Header(rlp.decode(encodedHeader)))
cb(null, new Block.Header(rlp.decode(encodedHeader), {common: self._common}))
})
})
}
Expand Down
19 changes: 10 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,22 @@
},
"homepage": "https://github.com/ethereumjs/ethereumjs-blockchain#readme",
"dependencies": {
"async": "^2.1.2",
"async": "^2.6.1",
"ethashjs": "~0.0.7",
"ethereumjs-block": "~1.7.0",
"ethereumjs-block": "ethereumjs/ethereumjs-block#validate-fix",
"ethereumjs-common": "~0.4.0",
"ethereumjs-util": "~5.2.0",
"flow-stoplight": "^1.0.0",
"levelup": "^1.3.0",
"lru-cache": "^4.1.2",
"levelup": "^1.3.2",
"lru-cache": "^4.1.3",
"memdown": "^1.1.0",
"safe-buffer": "^5.1.1",
"semaphore": "^1.0.3"
"safe-buffer": "^5.1.2",
"semaphore": "^1.1.0"
},
"devDependencies": {
"coveralls": "^3.0.0",
"nyc": "^11.8.0",
"coveralls": "^3.0.2",
"nyc": "^13.0.1",
"standard": "^11.0.1",
"tape": "^4.2.1"
"tape": "^4.9.1"
}
}
51 changes: 50 additions & 1 deletion test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const test = require('tape')
const Blockchain = require('..')
const Block = require('ethereumjs-block')
const Common = require('ethereumjs-common')
const async = require('async')
const ethUtil = require('ethereumjs-util')
const levelup = require('levelup')
Expand All @@ -12,7 +13,7 @@ const BN = require('bn.js')
const rlp = ethUtil.rlp

test('blockchain test', function (t) {
t.plan(66)
t.plan(70)
var blockchain = new Blockchain()
var genesisBlock
var blocks = []
Expand All @@ -27,6 +28,22 @@ test('blockchain test', function (t) {
done()
})
},
function initialization (done) {
const common = new Common('ropsten')
t.throws(function () { new Blockchain({ chain: 'ropsten', common: common }) }, /not allowed!$/, 'should throw on initialization with chain and common parameter') // eslint-disable-line

const bc0 = new Blockchain({ chain: 'ropsten' })
const bc1 = new Blockchain({ common: common })
async.parallel([
(cb) => bc0.getHead(cb),
(cb) => bc1.getHead(cb)
], (err, heads) => {
if (err) return done(err)
t.equals(heads[0].hash().toString('hex'), common.genesis().hash.slice(2), 'correct genesis hash')
t.equals(heads[0].hash().toString('hex'), heads[1].hash().toString('hex'), 'genesis blocks match')
done()
})
},
function alternateConstructors (done) {
var db = levelup('', { db: memdown })
var blockchain = new Blockchain(db)
Expand Down Expand Up @@ -439,6 +456,38 @@ test('blockchain test', function (t) {
], cb)
})
], done)
},
function mismatchedChains (done) {
var common = new Common('rinkeby')
var blockchain = new Blockchain({common: common, validate: false})
var blocks = [
new Block(null, {common: common}),
new Block(null, {chain: 'rinkeby'}),
new Block(null, {chain: 'ropsten'})
]

blocks[0].setGenesisParams()

blocks[1].header.number = 1
blocks[1].header.parentHash = blocks[0].hash()

blocks[2].header.number = 2
blocks[2].header.parentHash = blocks[1].hash()

async.eachOfSeries(blocks, (block, i, cb) => {
if (i === 0) {
blockchain.putGenesis(block, cb)
} else {
blockchain.putBlock(block, (err) => {
if (i === 2) {
t.ok(err.message.match('Chain mismatch'), 'should return chain mismatch error')
} else {
t.error(err, 'should not return mismatch error')
}
cb()
})
}
})
}
], function (err) {
if (err) {
Expand Down

0 comments on commit 2e1671d

Please sign in to comment.