Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
c053761
block -> refactor: reworked header class with static factory instanti…
holgerd77 Sep 21, 2020
ff46c55
block -> refactoring: added new static factory helpers to block class
holgerd77 Sep 21, 2020
dd228bc
block -> refactor: fix build errors, remove unused imports, unpad num…
jochem-brouwer Sep 24, 2020
608d804
block -> rename Header to BlockHeader
jochem-brouwer Sep 28, 2020
17a33a8
block/tx -> fix block tests
jochem-brouwer Sep 28, 2020
72b5b78
block -> enforce BNs on fields which are interpreted as numbers
jochem-brouwer Sep 28, 2020
8adcdf9
block -> edge case in toBN
jochem-brouwer Sep 29, 2020
8987003
ethash -> make ethash compatible with block
jochem-brouwer Sep 29, 2020
5f5e9f2
Merge branch 'master' into refactor-block-library
ryanio Oct 7, 2020
5351fb8
have validateTransactions return a string[] (https://github.com/ether…
ryanio Oct 7, 2020
ce1dac1
let => const
ryanio Oct 7, 2020
526f986
set default param to resolve js runtime check
ryanio Oct 7, 2020
75689e6
continue refactoring and simplifying methods
ryanio Oct 8, 2020
8923f71
api updates
ryanio Oct 8, 2020
6a2c193
continuing work
ryanio Oct 8, 2020
381f5e1
inline buffer validations. add checks for extraData, mixHash and nonce
ryanio Oct 8, 2020
7eecf80
various fixups
ryanio Oct 8, 2020
395c6f8
continuing various work
ryanio Oct 9, 2020
be5c8d2
continuing work and refactoring
ryanio Oct 9, 2020
7fa486d
Merge branch 'master' into refactor-block-library
ryanio Oct 9, 2020
91d45d7
re-add timestamp to genesis (for rinkeby)
ryanio Oct 9, 2020
7e788c3
last fixups
ryanio Oct 9, 2020
bc459e8
update readme, benchmarks
ryanio Oct 9, 2020
ea8a401
update vm readme, simplify validate
ryanio Oct 10, 2020
b694010
fix timestamp validation
ryanio Oct 10, 2020
1f66378
use native eq
ryanio Oct 10, 2020
9f9bab0
make blockchain optional in block.validate()
ryanio Oct 10, 2020
7ce9132
fixups
ryanio Oct 10, 2020
a5d3d14
remove BLOCK_difficulty_GivenAsList from skip list (https://github.co…
ryanio Oct 12, 2020
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
Prev Previous commit
Next Next commit
continuing various work
  • Loading branch information
ryanio committed Oct 9, 2020
commit 395c6f86d7e6e92b4bc7222b875c64fc74019a60
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/account/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
},
"homepage": "https://github.com/ethereumjs/ethereumjs-vm/tree/master/packages/account#synopsis",
"dependencies": {
"ethereumjs-util": "^7.0.5",
"ethereumjs-util": "^7.0.6",
"rlp": "^2.2.3",
"safe-buffer": "^5.1.1"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/block/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"@ethereumjs/common": "^1.5.1",
"@ethereumjs/tx": "^2.1.2",
"@types/bn.js": "^4.11.6",
"ethereumjs-util": "^7.0.5",
"ethereumjs-util": "^7.0.6",
"merkle-patricia-tree": "^4.0.0"
},
"devDependencies": {
Expand Down
54 changes: 23 additions & 31 deletions packages/block/src/block.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { BaseTrie as Trie } from 'merkle-patricia-tree'
import { BN, rlp, keccak256, KECCAK256_RLP } from 'ethereumjs-util'
import { rlp, keccak256, KECCAK256_RLP } from 'ethereumjs-util'
import Common from '@ethereumjs/common'
import { Transaction, TxOptions } from '@ethereumjs/tx'
import { BlockHeader } from './header'
import { BlockData, BlockOptions, JsonBlock, Blockchain } from './types'
import { BlockData, BlockOptions, JsonBlock, BlockBuffer, Blockchain } from './types'

/**
* An object that represents the block
* An object that represents the block.
*/
export class Block {
public readonly header: BlockHeader
Expand Down Expand Up @@ -38,13 +38,7 @@ export class Block {
}

public static fromRLPSerializedBlock(serialized: Buffer, opts: BlockOptions = {}) {
const values = (rlp.decode(serialized) as any) as [Buffer[], Buffer[][], Buffer[][]]
// Here we cast to silence TS errors,
// we know that values is
// [ Header: Buffer[],
// Transactions: Buffer[][],
// UncleHeaders: Buffer[][]
// ]
const values = (rlp.decode(serialized) as any) as BlockBuffer

if (!Array.isArray(values)) {
throw new Error('Invalid serialized block input. Must be array')
Expand All @@ -53,30 +47,25 @@ export class Block {
return Block.fromValuesArray(values, opts)
}

public static fromValuesArray(
values: [Buffer[], Buffer[][], Buffer[][]],
opts: BlockOptions = {},
) {
public static fromValuesArray(values: BlockBuffer, opts: BlockOptions = {}) {
if (values.length > 3) {
throw new Error('invalid block. More values than expected were received')
}

const headerArray = values[0] || []
const txsData = values[1] || []
const uncleHeadersData = values[2] || []
const [headerData, txsData, uhsData] = values

const header = BlockHeader.fromValuesArray(headerArray, opts)
const header = BlockHeader.fromValuesArray(headerData, opts)

// parse transactions
const transactions = []
for (const txData of txsData) {
transactions.push(Transaction.fromValuesArray(txData as Buffer[], opts as TxOptions))
for (const txData of txsData || []) {
transactions.push(Transaction.fromValuesArray(txData, opts))
}

// parse uncle headers
const uncleHeaders = []
for (const uncleHeaderData of uncleHeadersData) {
uncleHeaders.push(BlockHeader.fromValuesArray(uncleHeaderData as Buffer[], opts))
for (const uncleHeaderData of uhsData || []) {
uncleHeaders.push(BlockHeader.fromValuesArray(uncleHeaderData, opts))
}

return new Block(header, transactions, uncleHeaders)
Expand All @@ -100,23 +89,26 @@ export class Block {
Object.freeze(this)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For understanding on further implications: does this Object.freeze() mean we can't do further modifications on e.g. the Common instance passed?

So would a subsequent call (e.g. in a VM context) common.setHardfork('byzantium') (or whatever) throw in this context or would this still work?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll have to give it a test, but I think the common object can still update, it just can't be set to a totally new instance (e.g. block._common = newCommon would fail)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I think this is the case according to here:

Note that values that are objects can still be modified, unless they are also frozen.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze

}

get raw() {
/**
* Returns a Buffer Array of the raw Buffers of this block, in order.
*/
raw(): BlockBuffer {
return [
this.header.raw(),
this.transactions.map((tx) => tx.serialize()),
this.transactions.map((tx) => tx.raw()),
this.uncleHeaders.map((uh) => uh.raw()),
]
}

/**
* Produces a hash the RLP of the block
* Produces a hash the RLP of the block.
*/
hash(): Buffer {
return this.header.hash()
}

/**
* Determines if this block is the genesis block
* Determines if this block is the genesis block.
*/
isGenesis(): boolean {
return this.header.isGenesis()
Expand All @@ -126,7 +118,7 @@ export class Block {
* Returns the rlp encoding of the block.
*/
serialize(): Buffer {
return rlp.encode(this.raw)
return rlp.encode(this.raw())
}

/**
Expand All @@ -141,7 +133,7 @@ export class Block {
}

/**
* Validates the transaction trie
* Validates the transaction trie.
*/
validateTransactionsTrie(): boolean {
if (this.transactions.length > 0) {
Expand All @@ -152,7 +144,7 @@ export class Block {
}

/**
* Validates the transactions
* Validates the transactions.
*
* @param stringError - If `true`, a string with the indices of the invalid txs is returned.
*/
Expand Down Expand Up @@ -199,7 +191,7 @@ export class Block {
}

/**
* Validates the uncle's hash
* Validates the uncle's hash.
*/
validateUnclesHash(): boolean {
const raw = rlp.encode(this.uncleHeaders.map((uh) => uh.raw()))
Expand Down Expand Up @@ -251,7 +243,7 @@ export class Block {
// This is not possible in ethereumjs-blockchain since this PR was merged:
// https://github.com/ethereumjs/ethereumjs-blockchain/pull/47

const height = new BN(this.header.number)
const height = this.header.number
return uncleHeader.validate(blockchain, height)
}
}
40 changes: 8 additions & 32 deletions packages/block/src/from-rpc.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Transaction, TxData } from '@ethereumjs/tx'
import { toBuffer, setLengthLeft, Address } from 'ethereumjs-util'
import { toBuffer, setLengthLeft } from 'ethereumjs-util'
import { Block, BlockOptions } from './index'

import blockHeaderFromRpc from './header-from-rpc'
Expand All @@ -11,46 +11,22 @@ import blockHeaderFromRpc from './header-from-rpc'
* @param uncles - Optional list of Ethereum JSON RPC of uncles (eth_getUncleByBlockHashAndIndex)
* @param chainOptions - An object describing the blockchain
*/
export default function blockFromRpc(blockParams: any, uncles?: any[], options?: BlockOptions) {
uncles = uncles || []

export default function blockFromRpc(blockParams: any, uncles: any[] = [], options?: BlockOptions) {
const header = blockHeaderFromRpc(blockParams, options)

const transactions: TxData[] = []

const transactions: Transaction[] = []
if (blockParams.transactions) {
const txOpts = { common: header._common }

const opts = { common: header._common }
for (const _txParams of blockParams.transactions) {
const txParams = normalizeTxParams(_txParams)

// override from address
const fromAddress = txParams.from ? Address.fromString(txParams.from) : Address.zero()
delete txParams.from

const tx = Transaction.fromTxData(txParams as TxData, txOpts)
const fakeTx = Object.create(tx)

// override getSenderAddress
fakeTx.getSenderAddress = () => {
return fromAddress
}
// override hash
fakeTx.hash = () => {
return toBuffer(txParams.hash)
}

transactions.push(fakeTx)
const tx = Transaction.fromTxData(txParams as TxData, opts)
transactions.push(tx)
}
}

const block = Block.fromBlockData({
header,
transactions,
uncleHeaders: uncles.map((uh) => blockHeaderFromRpc(uh, options)),
})
const uncleHeaders = uncles.map((uh) => blockHeaderFromRpc(uh, options))

return block
return Block.fromBlockData({ header, transactions, uncleHeaders })
}

function normalizeTxParams(_txParams: any) {
Expand Down
55 changes: 34 additions & 21 deletions packages/block/src/header-from-rpc.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { BlockHeader } from './header'
import { KECCAK256_NULL, toBuffer } from 'ethereumjs-util'
import { BlockOptions } from './types'

/**
Expand All @@ -9,31 +8,45 @@ import { BlockOptions } from './types'
* @param chainOptions - An object describing the blockchain
*/
export default function blockHeaderFromRpc(blockParams: any, options?: BlockOptions) {
const {
parentHash,
sha3Uncles,
miner,
stateRoot,
transactionsRoot,
receiptRoot,
receiptsRoot,
logsBloom,
difficulty,
number,
gasLimit,
gasUsed,
timestamp,
extraData,
mixHash,
nonce,
} = blockParams

const blockHeader = BlockHeader.fromHeaderData(
{
parentHash: blockParams.parentHash,
uncleHash: blockParams.sha3Uncles,
coinbase: blockParams.miner,
stateRoot: blockParams.stateRoot,
transactionsTrie: blockParams.transactionsRoot,
receiptTrie: blockParams.receiptRoot || blockParams.receiptsRoot || KECCAK256_NULL,
bloom: blockParams.logsBloom,
difficulty: blockParams.difficulty,
number: blockParams.number,
gasLimit: blockParams.gasLimit,
gasUsed: blockParams.gasUsed,
timestamp: blockParams.timestamp,
extraData: blockParams.extraData,
mixHash: blockParams.mixHash,
nonce: blockParams.nonce,
parentHash,
uncleHash: sha3Uncles,
coinbase: miner,
stateRoot,
transactionsTrie: transactionsRoot,
receiptTrie: receiptRoot || receiptsRoot,
bloom: logsBloom,
difficulty,
number,
gasLimit,
gasUsed,
timestamp,
extraData,
mixHash,
nonce,
},
options,
)

// override hash in case something was missing TODO: why do we need this?
//blockHeader.hash = function () {
// return toBuffer(blockParams.hash)
//}

return blockHeader
}
Loading