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

[MASTER-RELEASE] Byzantium changes #32

Merged
merged 6 commits into from
Sep 25, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
[Semantic Versioning](http://semver.org/spec/v2.0.0.html).


## [1.7.0] - Unreleased
- TODO
## [1.7.0] - Unreleased (``master`` branch)
- ``Metro-Byzantium`` compatible
- New difficulty formula (EIP 100)
- Difficulty bomb delay (EIP 649)
- Removed ``isHomestead``, ``isHomesteadReprice`` from API methods

[1.7.0]: https://github.com/ethereumjs/ethereumjs-vm/compare/v1.6.0...v1.7.0

Expand Down
12 changes: 0 additions & 12 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,6 @@ Determines if a given block is the genesis block

Returns **any** Boolean

## isHomestead

Determines if a given block part of homestead or not

Returns **any** Boolean

## isHomesteadReprice

Determines if a given block part of homestead reprice or not

Returns **any** Boolean

## setGenesisParams

turns the block in to the canonical genesis block
Expand Down
51 changes: 16 additions & 35 deletions header.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,26 +93,24 @@ BlockHeader.prototype.canonicalDifficulty = function (parentBlock) {
var offset = parentDif.div(new BN(params.difficultyBoundDivisor.v))
var dif

if (this.isHomestead()) {
// homestead
// 1 - (block_timestamp - parent_timestamp) // 10
var a = blockTs.sub(parentTs).idivn(10).ineg().iaddn(1)
var cutoff = new BN(-99)
// MAX(cutoff, a)
if (cutoff.cmp(a) === 1) {
a = cutoff
}
dif = parentDif.add(offset.mul(a))
} else {
// prehomestead
if (parentTs.addn(params.durationLimit.v).cmp(blockTs) === 1) {
dif = offset.add(parentDif)
} else {
dif = parentDif.sub(offset)
}
// Byzantium
// max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99)
var uncleAddend = parentBlock.header.uncleHash.equals(utils.SHA3_RLP_ARRAY) ? 1 : 2
var a = blockTs.sub(parentTs).idivn(9).ineg().iaddn(uncleAddend)
var cutoff = new BN(-99)
// MAX(cutoff, a)
if (cutoff.cmp(a) === 1) {
a = cutoff
}
dif = parentDif.add(offset.mul(a))

// Byzantium difficulty bomb delay
var num = new BN(this.number).isubn(3000000)
if (num.ltn(0)) {
num = new BN(0)
}

var exp = new BN(this.number).idivn(100000).isubn(2)
var exp = num.idivn(100000).isubn(2)
if (!exp.isNeg()) {
dif.iadd(new BN(2).pow(exp))
}
Expand Down Expand Up @@ -231,20 +229,3 @@ BlockHeader.prototype.isGenesis = function () {
return this.number.toString('hex') === ''
}

/**
* Determines if a given block part of homestead or not
* @method isHomestead
* @return Boolean
*/
BlockHeader.prototype.isHomestead = function () {
return utils.bufferToInt(this.number) >= params.homeSteadForkNumber.v
}

/**
* Determines if a given block part of Homestead Reprice (EIP150) or not
* @method isHomesteadReprice
* @return Boolean
*/
BlockHeader.prototype.isHomesteadReprice = function () {
return utils.bufferToInt(this.number) >= params.homesteadRepriceForkNumber.v
}
21 changes: 1 addition & 20 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,10 @@ var Block = module.exports = function (data) {
this.uncleHeaders.push(new BlockHeader(rawUncleHeaders[i]))
}

var homestead = this.isHomestead()
// parse transactions
for (i = 0; i < rawTransactions.length; i++) {
var tx = new Tx(rawTransactions[i])
tx._homestead = homestead
tx._homestead = true
this.transactions.push(tx)
}
}
Expand All @@ -81,24 +80,6 @@ Block.prototype.isGenesis = function () {
return this.header.isGenesis()
}

/**
* Determines if a given block part of homestead or not
* @method isHomestead
* @return Boolean
*/
Block.prototype.isHomestead = function () {
return this.header.isHomestead()
}

/**
* Determines if a given block part of homestead reprice or not
* @method isHomesteadReprice
* @return Boolean
*/
Block.prototype.isHomesteadReprice = function () {
return this.header.isHomesteadReprice()
}

/**
* turns the block in to the canonical genesis block
* @method setGenesisParams
Expand Down
49 changes: 30 additions & 19 deletions tests/difficulty.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const testing = require('ethereumjs-testing')
// const testing = require('ethereumjs-testing')
const utils = require('ethereumjs-util')
const tape = require('tape')
const Block = require('../')
Expand All @@ -13,32 +13,43 @@ function normalize (data) {
}

tape('[Header]: difficulty tests', t => {
let args = {}
args.file = /^difficultyHomestead/
testing.getTestsFromArgs('BasicTests', (fileName, testName, test) => {
return new Promise((resolve, reject) => {
normalize(test)
function runDifficultyTests (test) {
normalize(test)

var parentBlock = new Block()
parentBlock.header.timestamp = test.parentTimestamp
parentBlock.header.difficulty = test.parentDifficulty
var parentBlock = new Block()
parentBlock.header.timestamp = test.parentTimestamp
parentBlock.header.difficulty = test.parentDifficulty
parentBlock.header.uncleHash = test.parentUncles

var block = new Block()
block.header.isHomestead = function () {
return true
}
var block = new Block()
block.header.timestamp = test.currentTimestamp
block.header.difficulty = test.currentDifficulty
block.header.number = test.currentBlockNumber

block.header.timestamp = test.currentTimestamp
block.header.difficulty = test.currentDifficulty
block.header.number = test.currentBlockNumber
var dif = block.header.canonicalDifficulty(parentBlock)
t.equal(dif.toString(), test.currentDifficulty.toString(), 'test canonicalDifficulty')
t.assert(block.header.validateDifficulty(parentBlock), 'test validateDifficulty')
}

var dif = block.header.canonicalDifficulty(parentBlock)
t.equal(dif.toString(), test.currentDifficulty.toString(), 'test canonicalDifficulty')
t.assert(block.header.validateDifficulty(parentBlock), 'test validateDifficulty')
const testData = require('./testdata-difficulty.json')
for (let testName in testData) {
runDifficultyTests(testData[testName])
}
t.end()

// Temporarily run local test selection
// also: implicit testing through ethereumjs-vm tests
// (no Byzantium difficulty tests available yet)
/*
let args = {}
args.file = /^difficultyHomestead/
testing.getTestsFromArgs('BasicTests', (fileName, testName, test) => {
return new Promise((resolve, reject) => {
runDifficultyTests(test)
resolve()
}).catch(err => console.log(err))
}, args).then(() => {
t.end()
})
*/
})
Loading