Skip to content

Commit

Permalink
blockchain: add DBInterface, fix test
Browse files Browse the repository at this point in the history
  • Loading branch information
jochem-brouwer committed Oct 21, 2020
1 parent f69f144 commit 0f08e62
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 30 deletions.
Empty file.
18 changes: 18 additions & 0 deletions packages/blockchain/src/db/DBInterface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { BN } from 'ethereumjs-util'
import { Block, BlockHeader } from '@ethereumjs/block'

export type BlockIdentifier = BN | Buffer // either a Block number or a BlockHash

export interface BlockchainDB {
putTD(blockIdentifier: BlockIdentifier): Promise<void>
getTD(blockIdentifier: BlockIdentifier): Promise<BN>

putBlock(block: Block): Promise<void>
getBlock(blockIdentifier: BlockIdentifier): Promise<Block>

putBlockHeader(header: BlockHeader): Promise<void>
getBlockHeader(blockIdentifier: BlockIdentifier): Promise<BlockHeader>

getNumberByHash(hash: Buffer): Promise<BN>
getHashByNumber(number: BN): Promise<Buffer>
}
72 changes: 46 additions & 26 deletions packages/blockchain/test/reorg.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,43 @@
import Common from '@ethereumjs/common'
import { Block, BlockHeader } from '@ethereumjs/block'
import { BN, toBuffer, bufferToInt } from 'ethereumjs-util'
import * as test from 'tape'
import { Block } from '@ethereumjs/block'
import { BN } from 'ethereumjs-util'
import tape from 'tape'
import Blockchain from '../src'
import { generateBlocks, generateConsecutiveBlock } from './util'
import * as testData from './testdata.json'

const level = require('level-mem')

const genesis = generateBlocks(1)[0]
genesis.header.difficulty = Buffer.from('02000', 'hex') // minimum difficulty
import { generateConsecutiveBlock } from './util'

const genesis = Block.fromBlockData({
header: {
number: new BN(0),
difficulty: new BN(0x020000),
gasLimit: new BN(8000000),
},
})

test('reorg tests', (t) => {
tape('reorg tests', (t) => {
t.test(
'should correctly reorg the chain if the total difficulty is higher on a lower block number than the current head block',
async (st) => {
const common = new Common({ chain: 'mainnet', hardfork: 'muirGlacier' })
const blockchain = new Blockchain({ validateBlocks: true, validatePow: false, common })
await blockchain.putBlock(genesis, true)

let blocks_lowTD: Block[] = []
let blocks_highTD: Block[] = []
const blocks_lowTD: Block[] = []
const blocks_highTD: Block[] = []

blocks_lowTD.push(generateConsecutiveBlock(genesis, 0))

let TD_Low = new BN(genesis.header.difficulty).add(new BN(blocks_lowTD[0].header.difficulty))
let TD_High = new BN(genesis.header.difficulty)
const TD_Low = new BN(genesis.header.difficulty).add(
new BN(blocks_lowTD[0].header.difficulty)
)
const TD_High = new BN(genesis.header.difficulty)

// Keep generating blocks until the Total Difficulty (TD) of the High TD chain is higher than the TD of the Low TD chain
// This means that the block number of the high TD chain is 1 lower than the low TD chain

while (TD_High.cmp(TD_Low) == -1) {
blocks_lowTD.push(generateConsecutiveBlock(blocks_lowTD[blocks_lowTD.length - 1], 0))
blocks_highTD.push(
generateConsecutiveBlock(blocks_highTD[blocks_highTD.length - 1] || genesis, 1),
generateConsecutiveBlock(blocks_highTD[blocks_highTD.length - 1] || genesis, 1)
)

TD_Low.iadd(new BN(blocks_lowTD[blocks_lowTD.length - 1].header.difficulty))
Expand All @@ -44,23 +48,39 @@ test('reorg tests', (t) => {
const lowTDBlock = blocks_lowTD[blocks_lowTD.length - 1]
const highTDBlock = blocks_highTD[blocks_highTD.length - 1]

let number_lowTD = new BN(lowTDBlock.header.number)
let number_highTD = new BN(highTDBlock.header.number)

// ensure that the block number is indeed higher on the low TD chain
t.ok(number_lowTD.cmp(number_highTD) == 1)
const number_lowTD = new BN(lowTDBlock.header.number)
const number_highTD = new BN(highTDBlock.header.number)

// ensure that the block difficulty is higher on the highTD chain when compared to the low TD chain
t.ok(
number_lowTD.cmp(number_highTD) == 1,
'low TD should have a lower TD than the reported high TD'
)
t.ok(
blocks_lowTD[blocks_lowTD.length - 1].header.number.gt(
blocks_highTD[blocks_highTD.length - 1].header.number
),
'low TD block should have a higher number than high TD block'
)

await blockchain.putBlocks(blocks_lowTD)

let head_lowTD = await blockchain.getHead()
const head_lowTD = await blockchain.getHead()

await blockchain.putBlocks(blocks_highTD)

let head_highTD = await blockchain.getHead()
const head_highTD = await blockchain.getHead()

t.ok(
head_lowTD.hash().equals(lowTDBlock.hash()),
'head on the low TD chain should equal the low TD block'
)
t.ok(
head_highTD.hash().equals(highTDBlock.hash()),
'head on the high TD chain should equal the high TD block'
)

t.ok(head_lowTD.hash().equals(lowTDBlock.hash()))
t.ok(head_highTD.hash().equals(highTDBlock.hash()))
st.end()
},
}
)
})
9 changes: 5 additions & 4 deletions packages/blockchain/test/util.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { BN, rlp, toBuffer } from 'ethereumjs-util'
import { BN, rlp } from 'ethereumjs-util'
import { Block, BlockHeader } from '@ethereumjs/block'
import Common from '@ethereumjs/common'
import Blockchain from '../src'
Expand Down Expand Up @@ -54,6 +54,7 @@ export const generateBlockchain = async (numberOfBlocks: number, genesis?: Block
blocks,
error: null,
}
}
/**
*
* @param parentBlock parent block to generate the consecutive block on top of
Expand All @@ -62,7 +63,7 @@ export const generateBlockchain = async (numberOfBlocks: number, genesis?: Block

export const generateConsecutiveBlock = (
parentBlock: Block,
difficultyChangeFactor: number,
difficultyChangeFactor: number
): Block => {
if (difficultyChangeFactor > 1) {
difficultyChangeFactor = 1
Expand All @@ -78,11 +79,11 @@ export const generateConsecutiveBlock = (
parentHash: parentBlock.hash(),
gasLimit: new BN(8000000),
timestamp: parentBlock.header.timestamp.addn(10 + -difficultyChangeFactor * 9),
difficulty: new BN(tmpHeader.canonicalDifficulty(parentBlock)),
difficulty: new BN(tmpHeader.canonicalDifficulty(parentBlock.header)),
},
{
common,
},
}
)

const block = new Block(header, undefined, undefined, { common })
Expand Down

0 comments on commit 0f08e62

Please sign in to comment.