diff --git a/core/block_cache_test.go b/core/block_cache_test.go
index 43ab847f973012bca9526b5a3e14d713d63fc266..80d1185993245ffa93fb360f496c61761818ca88 100644
--- a/core/block_cache_test.go
+++ b/core/block_cache_test.go
@@ -11,12 +11,12 @@ import (
 func newChain(size int) (chain []*types.Block) {
 	var parentHash common.Hash
 	for i := 0; i < size; i++ {
-		block := types.NewBlock(parentHash, common.Address{}, common.Hash{}, new(big.Int), 0, nil)
-		block.Header().Number = big.NewInt(int64(i))
+		head := &types.Header{ParentHash: parentHash, Number: big.NewInt(int64(i))}
+		block := types.NewBlock(head, nil, nil, nil)
 		chain = append(chain, block)
 		parentHash = block.Hash()
 	}
-	return
+	return chain
 }
 
 func insertChainCache(cache *BlockCache, chain []*types.Block) {
diff --git a/core/block_processor.go b/core/block_processor.go
index e30ced3128da07594b246dc3f140903c814e8744..2fd8c04c021c7932bc438f05587fc47dca1232aa 100644
--- a/core/block_processor.go
+++ b/core/block_processor.go
@@ -57,8 +57,8 @@ func NewBlockProcessor(db, extra common.Database, pow pow.PoW, chainManager *Cha
 }
 
 func (sm *BlockProcessor) TransitionState(statedb *state.StateDB, parent, block *types.Block, transientProcess bool) (receipts types.Receipts, err error) {
-	coinbase := statedb.GetOrNewStateObject(block.Header().Coinbase)
-	coinbase.SetGasLimit(block.Header().GasLimit)
+	coinbase := statedb.GetOrNewStateObject(block.Coinbase())
+	coinbase.SetGasLimit(block.GasLimit())
 
 	// Process the transactions on to parent state
 	receipts, err = sm.ApplyTransactions(coinbase, statedb, block, block.Transactions(), transientProcess)
@@ -69,11 +69,11 @@ func (sm *BlockProcessor) TransitionState(statedb *state.StateDB, parent, block
 	return receipts, nil
 }
 
-func (self *BlockProcessor) ApplyTransaction(coinbase *state.StateObject, statedb *state.StateDB, block *types.Block, tx *types.Transaction, usedGas *big.Int, transientProcess bool) (*types.Receipt, *big.Int, error) {
+func (self *BlockProcessor) ApplyTransaction(coinbase *state.StateObject, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *big.Int, transientProcess bool) (*types.Receipt, *big.Int, error) {
 	// If we are mining this block and validating we want to set the logs back to 0
 
 	cb := statedb.GetStateObject(coinbase.Address())
-	_, gas, err := ApplyMessage(NewEnv(statedb, self.bc, tx, block), tx, cb)
+	_, gas, err := ApplyMessage(NewEnv(statedb, self.bc, tx, header), tx, cb)
 	if err != nil && (IsNonceErr(err) || state.IsGasLimitErr(err) || IsInvalidTxErr(err)) {
 		return nil, nil, err
 	}
@@ -108,12 +108,13 @@ func (self *BlockProcessor) ApplyTransactions(coinbase *state.StateObject, state
 		totalUsedGas  = big.NewInt(0)
 		err           error
 		cumulativeSum = new(big.Int)
+		header        = block.Header()
 	)
 
 	for i, tx := range txs {
 		statedb.StartRecord(tx.Hash(), block.Hash(), i)
 
-		receipt, txGas, err := self.ApplyTransaction(coinbase, statedb, block, tx, totalUsedGas, transientProcess)
+		receipt, txGas, err := self.ApplyTransaction(coinbase, statedb, header, tx, totalUsedGas, transientProcess)
 		if err != nil && (IsNonceErr(err) || state.IsGasLimitErr(err) || IsInvalidTxErr(err)) {
 			return nil, err
 		}
@@ -142,11 +143,10 @@ func (sm *BlockProcessor) RetryProcess(block *types.Block) (logs state.Logs, err
 	sm.mutex.Lock()
 	defer sm.mutex.Unlock()
 
-	header := block.Header()
-	if !sm.bc.HasBlock(header.ParentHash) {
-		return nil, ParentError(header.ParentHash)
+	if !sm.bc.HasBlock(block.ParentHash()) {
+		return nil, ParentError(block.ParentHash())
 	}
-	parent := sm.bc.GetBlock(header.ParentHash)
+	parent := sm.bc.GetBlock(block.ParentHash())
 
 	// FIXME Change to full header validation. See #1225
 	errch := make(chan bool)
@@ -168,30 +168,32 @@ func (sm *BlockProcessor) Process(block *types.Block) (logs state.Logs, err erro
 	sm.mutex.Lock()
 	defer sm.mutex.Unlock()
 
-	header := block.Header()
-	if sm.bc.HasBlock(header.Hash()) {
-		return nil, &KnownBlockError{header.Number, header.Hash()}
+	if sm.bc.HasBlock(block.Hash()) {
+		return nil, &KnownBlockError{block.Number(), block.Hash()}
 	}
 
-	if !sm.bc.HasBlock(header.ParentHash) {
-		return nil, ParentError(header.ParentHash)
+	if !sm.bc.HasBlock(block.ParentHash()) {
+		return nil, ParentError(block.ParentHash())
 	}
-	parent := sm.bc.GetBlock(header.ParentHash)
+	parent := sm.bc.GetBlock(block.ParentHash())
 	return sm.processWithParent(block, parent)
 }
 
 func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (logs state.Logs, err error) {
 	// Create a new state based on the parent's root (e.g., create copy)
 	state := state.New(parent.Root(), sm.db)
+	header := block.Header()
+	uncles := block.Uncles()
+	txs := block.Transactions()
 
 	// Block validation
-	if err = ValidateHeader(sm.Pow, block.Header(), parent.Header(), false); err != nil {
+	if err = ValidateHeader(sm.Pow, header, parent.Header(), false); err != nil {
 		return
 	}
 
 	// There can be at most two uncles
-	if len(block.Uncles()) > 2 {
-		return nil, ValidationError("Block can only contain maximum 2 uncles (contained %v)", len(block.Uncles()))
+	if len(uncles) > 2 {
+		return nil, ValidationError("Block can only contain maximum 2 uncles (contained %v)", len(uncles))
 	}
 
 	receipts, err := sm.TransitionState(state, parent, block, false)
@@ -199,8 +201,6 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (logs st
 		return
 	}
 
-	header := block.Header()
-
 	// Validate the received block's bloom with the one derived from the generated receipts.
 	// For valid blocks this should always validate to true.
 	rbloom := types.CreateBloom(receipts)
@@ -211,7 +211,7 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (logs st
 
 	// The transactions Trie's root (R = (Tr [[i, RLP(T1)], [i, RLP(T2)], ... [n, RLP(Tn)]]))
 	// can be used by light clients to make sure they've received the correct Txs
-	txSha := types.DeriveSha(block.Transactions())
+	txSha := types.DeriveSha(txs)
 	if txSha != header.TxHash {
 		err = fmt.Errorf("invalid transaction root hash. received=%x calculated=%x", header.TxHash, txSha)
 		return
@@ -225,7 +225,7 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (logs st
 	}
 
 	// Verify UncleHash before running other uncle validations
-	unclesSha := block.CalculateUnclesHash()
+	unclesSha := types.CalcUncleHash(uncles)
 	if unclesSha != header.UncleHash {
 		err = fmt.Errorf("invalid uncles root hash. received=%x calculated=%x", header.UncleHash, unclesSha)
 		return
@@ -236,7 +236,7 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (logs st
 		return
 	}
 	// Accumulate static rewards; block reward, uncle's and uncle inclusion.
-	AccumulateRewards(state, block)
+	AccumulateRewards(state, header, uncles)
 
 	// Commit state objects/accounts to a temporary trie (does not save)
 	// used to calculate the state root.
@@ -260,11 +260,34 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (logs st
 	return state.Logs(), nil
 }
 
+// AccumulateRewards credits the coinbase of the given block with the
+// mining reward. The total reward consists of the static block reward
+// and rewards for included uncles.
+func AccumulateRewards(statedb *state.StateDB, header *types.Header, uncles []*types.Header) {
+	reward := new(big.Int).Set(BlockReward)
+
+	for _, uncle := range uncles {
+		num := new(big.Int).Add(big.NewInt(8), uncle.Number)
+		num.Sub(num, header.Number)
+
+		r := new(big.Int)
+		r.Mul(BlockReward, num)
+		r.Div(r, big.NewInt(8))
+
+		statedb.AddBalance(uncle.Coinbase, r)
+
+		reward.Add(reward, new(big.Int).Div(BlockReward, big.NewInt(32)))
+	}
+
+	// Get the account associated with the coinbase
+	statedb.AddBalance(header.Coinbase, reward)
+}
+
 func (sm *BlockProcessor) VerifyUncles(statedb *state.StateDB, block, parent *types.Block) error {
 	ancestors := set.New()
 	uncles := set.New()
 	ancestorHeaders := make(map[common.Hash]*types.Header)
-	for _, ancestor := range sm.bc.GetAncestors(block, 7) {
+	for _, ancestor := range sm.bc.GetBlocksFromHash(block.ParentHash(), 7) {
 		ancestorHeaders[ancestor.Hash()] = ancestor.Header()
 		ancestors.Add(ancestor.Hash())
 		// Include ancestors uncles in the uncle set. Uncles must be unique.
@@ -325,7 +348,7 @@ func (sm *BlockProcessor) GetLogs(block *types.Block) (logs state.Logs, err erro
 
 	// TODO: remove backward compatibility
 	var (
-		parent = sm.bc.GetBlock(block.Header().ParentHash)
+		parent = sm.bc.GetBlock(block.ParentHash())
 		state  = state.New(parent.Root(), sm.db)
 	)
 
@@ -341,7 +364,7 @@ func ValidateHeader(pow pow.PoW, block, parent *types.Header, checkPow bool) err
 		return fmt.Errorf("Block extra data too long (%d)", len(block.Extra))
 	}
 
-	expd := CalcDifficulty(block, parent)
+	expd := CalcDifficulty(int64(block.Time), int64(parent.Time), parent.Difficulty)
 	if expd.Cmp(block.Difficulty) != 0 {
 		return fmt.Errorf("Difficulty check failed for block %v, %v", block.Difficulty, expd)
 	}
@@ -375,26 +398,6 @@ func ValidateHeader(pow pow.PoW, block, parent *types.Header, checkPow bool) err
 	return nil
 }
 
-func AccumulateRewards(statedb *state.StateDB, block *types.Block) {
-	reward := new(big.Int).Set(BlockReward)
-
-	for _, uncle := range block.Uncles() {
-		num := new(big.Int).Add(big.NewInt(8), uncle.Number)
-		num.Sub(num, block.Number())
-
-		r := new(big.Int)
-		r.Mul(BlockReward, num)
-		r.Div(r, big.NewInt(8))
-
-		statedb.AddBalance(uncle.Coinbase, r)
-
-		reward.Add(reward, new(big.Int).Div(BlockReward, big.NewInt(32)))
-	}
-
-	// Get the account associated with the coinbase
-	statedb.AddBalance(block.Header().Coinbase, reward)
-}
-
 func getBlockReceipts(db common.Database, bhash common.Hash) (receipts types.Receipts, err error) {
 	var rdata []byte
 	rdata, err = db.Get(append(receiptsPre, bhash[:]...))
diff --git a/core/block_processor_test.go b/core/block_processor_test.go
index e38c815efea1d23b09bbdc95f02a419084e10cca..bd77a2fc2e8c6ccf0f5b5a6dd0e6cb99eab7cad6 100644
--- a/core/block_processor_test.go
+++ b/core/block_processor_test.go
@@ -26,20 +26,18 @@ func proc() (*BlockProcessor, *ChainManager) {
 }
 
 func TestNumber(t *testing.T) {
-	_, chain := proc()
-	block1 := chain.NewBlock(common.Address{})
-	block1.Header().Number = big.NewInt(3)
-	block1.Header().Time--
-
 	pow := ezp.New()
 
-	err := ValidateHeader(pow, block1.Header(), chain.Genesis().Header(), false)
+	bp, chain := proc()
+	header := makeHeader(chain.Genesis(), 0, bp.db, 0)
+	header.Number = big.NewInt(3)
+	err := ValidateHeader(pow, header, chain.Genesis().Header(), false)
 	if err != BlockNumberErr {
-		t.Errorf("expected block number error %v", err)
+		t.Errorf("expected block number error, got %q", err)
 	}
 
-	block1 = chain.NewBlock(common.Address{})
-	err = ValidateHeader(pow, block1.Header(), chain.Genesis().Header(), false)
+	header = makeHeader(chain.Genesis(), 0, bp.db, 0)
+	err = ValidateHeader(pow, header, chain.Genesis().Header(), false)
 	if err == BlockNumberErr {
 		t.Errorf("didn't expect block number error")
 	}
diff --git a/core/chain_makers.go b/core/chain_makers.go
index 76acfd6ca3d5b6165e0608c8bcb52d4b2a4f364f..e704fd08890c3abebdf2324c2d0fc2bfff93edfd 100644
--- a/core/chain_makers.go
+++ b/core/chain_makers.go
@@ -29,12 +29,8 @@ var (
 
 // Utility functions for making chains on the fly
 // Exposed for sake of testing from other packages (eg. go-ethash)
-func NewBlockFromParent(addr common.Address, parent *types.Block) *types.Block {
-	return newBlockFromParent(addr, parent)
-}
-
 func MakeBlock(bman *BlockProcessor, parent *types.Block, i int, db common.Database, seed int) *types.Block {
-	return makeBlock(bman, parent, i, db, seed)
+	return types.NewBlock(makeHeader(parent, i, db, seed), nil, nil, nil)
 }
 
 func MakeChain(bman *BlockProcessor, parent *types.Block, max int, db common.Database, seed int) types.Blocks {
@@ -53,46 +49,38 @@ func NewCanonical(n int, db common.Database) (*BlockProcessor, error) {
 	return newCanonical(n, db)
 }
 
-// block time is fixed at 10 seconds
-func newBlockFromParent(addr common.Address, parent *types.Block) *types.Block {
-	block := types.NewBlock(parent.Hash(), addr, parent.Root(), common.BigPow(2, 32), 0, nil)
-	block.SetUncles(nil)
-	block.SetTransactions(nil)
-	block.SetReceipts(nil)
-
-	header := block.Header()
-	header.Difficulty = CalcDifficulty(block.Header(), parent.Header())
-	header.Number = new(big.Int).Add(parent.Header().Number, common.Big1)
-	header.Time = parent.Header().Time + 10
-	header.GasLimit = CalcGasLimit(parent)
-
-	block.Td = parent.Td
-
-	return block
-}
-
-// Actually make a block by simulating what miner would do
-// we seed chains by the first byte of the coinbase
-func makeBlock(bman *BlockProcessor, parent *types.Block, i int, db common.Database, seed int) *types.Block {
+// makeHeader creates the header for a new empty block, simulating
+// what miner would do. We seed chains by the first byte of the coinbase.
+func makeHeader(parent *types.Block, i int, db common.Database, seed int) *types.Header {
 	var addr common.Address
-	addr[0], addr[19] = byte(seed), byte(i)
-	block := newBlockFromParent(addr, parent)
-	state := state.New(block.Root(), db)
+	addr[0], addr[19] = byte(seed), byte(i) // 'random' coinbase
+	time := parent.Time() + 10              // block time is fixed at 10 seconds
+
+	// ensure that the block's coinbase has the block reward in the state.
+	state := state.New(parent.Root(), db)
 	cbase := state.GetOrNewStateObject(addr)
 	cbase.SetGasLimit(CalcGasLimit(parent))
 	cbase.AddBalance(BlockReward)
 	state.Update()
-	block.SetRoot(state.Root())
-	return block
+
+	return &types.Header{
+		Root:       state.Root(),
+		ParentHash: parent.Hash(),
+		Coinbase:   addr,
+		Difficulty: CalcDifficulty(time, parent.Time(), parent.Difficulty()),
+		Number:     new(big.Int).Add(parent.Number(), common.Big1),
+		Time:       uint64(time),
+		GasLimit:   CalcGasLimit(parent),
+	}
 }
 
-// Make a chain with real blocks
-// Runs ProcessWithParent to get proper state roots
+// makeChain creates a valid chain of empty blocks.
 func makeChain(bman *BlockProcessor, parent *types.Block, max int, db common.Database, seed int) types.Blocks {
 	bman.bc.currentBlock = parent
 	blocks := make(types.Blocks, max)
 	for i := 0; i < max; i++ {
-		block := makeBlock(bman, parent, i, db, seed)
+		block := types.NewBlock(makeHeader(parent, i, db, seed), nil, nil, nil)
+		// Use ProcessWithParent to verify that we have produced a valid block.
 		_, err := bman.processWithParent(block, parent)
 		if err != nil {
 			fmt.Println("process with parent failed", err)
@@ -129,7 +117,7 @@ func newBlockProcessor(db common.Database, cman *ChainManager, eventMux *event.T
 }
 
 // Make a new, deterministic canonical chain by running InsertChain
-// on result of makeChain
+// on result of makeChain.
 func newCanonical(n int, db common.Database) (*BlockProcessor, error) {
 	eventMux := &event.TypeMux{}
 
diff --git a/core/chain_manager.go b/core/chain_manager.go
index 3b9b7517be80cbab9998841f2b5d23fb45405b1c..8a79e3e8adb9bb907e6eb68cffe533592755a19a 100644
--- a/core/chain_manager.go
+++ b/core/chain_manager.go
@@ -38,23 +38,24 @@ const (
 	maxTimeFutureBlocks = 30
 )
 
-func CalcDifficulty(block, parent *types.Header) *big.Int {
+// CalcDifficulty is the difficulty adjustment algorithm. It returns
+// the difficulty that a new block b should have when created at time
+// given the parent block's time and difficulty.
+func CalcDifficulty(time int64, parentTime int64, parentDiff *big.Int) *big.Int {
 	diff := new(big.Int)
-
-	adjust := new(big.Int).Div(parent.Difficulty, params.DifficultyBoundDivisor)
-	if big.NewInt(int64(block.Time)-int64(parent.Time)).Cmp(params.DurationLimit) < 0 {
-		diff.Add(parent.Difficulty, adjust)
+	adjust := new(big.Int).Div(parentDiff, params.DifficultyBoundDivisor)
+	if big.NewInt(time-parentTime).Cmp(params.DurationLimit) < 0 {
+		diff.Add(parentDiff, adjust)
 	} else {
-		diff.Sub(parent.Difficulty, adjust)
+		diff.Sub(parentDiff, adjust)
 	}
-
 	if diff.Cmp(params.MinimumDifficulty) < 0 {
 		return params.MinimumDifficulty
 	}
-
 	return diff
 }
 
+// CalcTD computes the total difficulty of block.
 func CalcTD(block, parent *types.Block) *big.Int {
 	if parent == nil {
 		return block.Difficulty()
@@ -62,6 +63,8 @@ func CalcTD(block, parent *types.Block) *big.Int {
 	return new(big.Int).Add(parent.Td, block.Header().Difficulty)
 }
 
+// CalcGasLimit computes the gas limit of the next block after parent.
+// The result may be modified by the caller.
 func CalcGasLimit(parent *types.Block) *big.Int {
 	decay := new(big.Int).Div(parent.GasLimit(), params.GasLimitBoundDivisor)
 	contrib := new(big.Int).Mul(parent.GasUsed(), big.NewInt(3))
@@ -71,11 +74,11 @@ func CalcGasLimit(parent *types.Block) *big.Int {
 	gl := new(big.Int).Sub(parent.GasLimit(), decay)
 	gl = gl.Add(gl, contrib)
 	gl = gl.Add(gl, big.NewInt(1))
-	gl = common.BigMax(gl, params.MinGasLimit)
+	gl.Set(common.BigMax(gl, params.MinGasLimit))
 
 	if gl.Cmp(params.GenesisGasLimit) < 0 {
-		gl2 := new(big.Int).Add(parent.GasLimit(), decay)
-		return common.BigMin(params.GenesisGasLimit, gl2)
+		gl.Add(parent.GasLimit(), decay)
+		gl.Set(common.BigMin(gl, params.GenesisGasLimit))
 	}
 	return gl
 }
@@ -255,50 +258,11 @@ func (bc *ChainManager) makeCache() {
 		bc.cache = NewBlockCache(blockCacheLimit)
 	}
 	// load in last `blockCacheLimit` - 1 blocks. Last block is the current.
-	ancestors := bc.GetAncestors(bc.currentBlock, blockCacheLimit-1)
-	ancestors = append(ancestors, bc.currentBlock)
-	for _, block := range ancestors {
+	for _, block := range bc.GetBlocksFromHash(bc.currentBlock.Hash(), blockCacheLimit) {
 		bc.cache.Push(block)
 	}
 }
 
-// Block creation & chain handling
-func (bc *ChainManager) NewBlock(coinbase common.Address) *types.Block {
-	bc.mu.RLock()
-	defer bc.mu.RUnlock()
-
-	var (
-		root       common.Hash
-		parentHash common.Hash
-	)
-
-	if bc.currentBlock != nil {
-		root = bc.currentBlock.Header().Root
-		parentHash = bc.lastBlockHash
-	}
-
-	block := types.NewBlock(
-		parentHash,
-		coinbase,
-		root,
-		common.BigPow(2, 32),
-		0,
-		nil)
-	block.SetUncles(nil)
-	block.SetTransactions(nil)
-	block.SetReceipts(nil)
-
-	parent := bc.currentBlock
-	if parent != nil {
-		header := block.Header()
-		header.Difficulty = CalcDifficulty(block.Header(), parent.Header())
-		header.Number = new(big.Int).Add(parent.Header().Number, common.Big1)
-		header.GasLimit = CalcGasLimit(parent)
-	}
-
-	return block
-}
-
 func (bc *ChainManager) Reset() {
 	bc.mu.Lock()
 	defer bc.mu.Unlock()
@@ -463,6 +427,19 @@ func (self *ChainManager) GetBlockByNumber(num uint64) *types.Block {
 
 }
 
+// GetBlocksFromHash returns the block corresponding to hash and up to n-1 ancestors.
+func (self *ChainManager) GetBlocksFromHash(hash common.Hash, n int) (blocks []*types.Block) {
+	for i := 0; i < n; i++ {
+		block := self.GetBlock(hash)
+		if block == nil {
+			break
+		}
+		blocks = append(blocks, block)
+		hash = block.ParentHash()
+	}
+	return
+}
+
 // non blocking version
 func (self *ChainManager) getBlockByNumber(num uint64) *types.Block {
 	key, _ := self.blockDb.Get(append(blockNumPre, big.NewInt(int64(num)).Bytes()...))
@@ -482,19 +459,6 @@ func (self *ChainManager) GetUnclesInChain(block *types.Block, length int) (uncl
 	return
 }
 
-func (self *ChainManager) GetAncestors(block *types.Block, length int) (blocks []*types.Block) {
-	for i := 0; i < length; i++ {
-		block = self.GetBlock(block.ParentHash())
-		if block == nil {
-			break
-		}
-
-		blocks = append(blocks, block)
-	}
-
-	return
-}
-
 // setTotalDifficulty updates the TD of the chain manager. Note, this function
 // assumes that the `mu` mutex is held!
 func (bc *ChainManager) setTotalDifficulty(td *big.Int) {
@@ -621,14 +585,12 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) {
 					return i, fmt.Errorf("%v: BlockFutureErr, %v > %v", BlockFutureErr, block.Time(), max)
 				}
 
-				block.SetQueued(true)
 				self.futureBlocks.Push(block)
 				stats.queued++
 				continue
 			}
 
 			if IsParentErr(err) && self.futureBlocks.Has(block.ParentHash()) {
-				block.SetQueued(true)
 				self.futureBlocks.Push(block)
 				stats.queued++
 				continue
diff --git a/core/chain_manager_test.go b/core/chain_manager_test.go
index c56a3b3e12a657be84d41288462f7d5d9b9f4f80..afec1d0f19d184469f1f28b7bc4a26e35636a436 100644
--- a/core/chain_manager_test.go
+++ b/core/chain_manager_test.go
@@ -117,7 +117,7 @@ func testChain(chainB types.Blocks, bman *BlockProcessor) (*big.Int, error) {
 }
 
 func loadChain(fn string, t *testing.T) (types.Blocks, error) {
-	fh, err := os.OpenFile(filepath.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "_data", fn), os.O_RDONLY, os.ModePerm)
+	fh, err := os.OpenFile(filepath.Join("..", "_data", fn), os.O_RDONLY, os.ModePerm)
 	if err != nil {
 		return nil, err
 	}
@@ -265,7 +265,7 @@ func TestBrokenChain(t *testing.T) {
 }
 
 func TestChainInsertions(t *testing.T) {
-	t.Skip() // travil fails.
+	t.Skip("Skipped: outdated test files")
 
 	db, _ := ethdb.NewMemDatabase()
 
@@ -303,7 +303,7 @@ func TestChainInsertions(t *testing.T) {
 }
 
 func TestChainMultipleInsertions(t *testing.T) {
-	t.Skip() // travil fails.
+	t.Skip("Skipped: outdated test files")
 
 	db, _ := ethdb.NewMemDatabase()
 
@@ -346,8 +346,8 @@ func TestChainMultipleInsertions(t *testing.T) {
 	}
 }
 
-func TestGetAncestors(t *testing.T) {
-	t.Skip() // travil fails.
+func TestGetBlocksFromHash(t *testing.T) {
+	t.Skip("Skipped: outdated test files")
 
 	db, _ := ethdb.NewMemDatabase()
 	chainMan := theChainManager(db, t)
@@ -361,8 +361,8 @@ func TestGetAncestors(t *testing.T) {
 		chainMan.write(block)
 	}
 
-	ancestors := chainMan.GetAncestors(chain[len(chain)-1], 4)
-	fmt.Println(ancestors)
+	blocks := chainMan.GetBlocksFromHash(chain[len(chain)-1].Hash(), 4)
+	fmt.Println(blocks)
 }
 
 type bproc struct{}
@@ -372,15 +372,17 @@ func (bproc) Process(*types.Block) (state.Logs, error) { return nil, nil }
 func makeChainWithDiff(genesis *types.Block, d []int, seed byte) []*types.Block {
 	var chain []*types.Block
 	for i, difficulty := range d {
-		header := &types.Header{Number: big.NewInt(int64(i + 1)), Difficulty: big.NewInt(int64(difficulty))}
-		block := types.NewBlockWithHeader(header)
-		copy(block.HeaderHash[:2], []byte{byte(i + 1), seed})
+		header := &types.Header{
+			Coinbase:   common.Address{seed},
+			Number:     big.NewInt(int64(i + 1)),
+			Difficulty: big.NewInt(int64(difficulty)),
+		}
 		if i == 0 {
-			block.ParentHeaderHash = genesis.Hash()
+			header.ParentHash = genesis.Hash()
 		} else {
-			copy(block.ParentHeaderHash[:2], []byte{byte(i), seed})
+			header.ParentHash = chain[i-1].Hash()
 		}
-
+		block := types.NewBlockWithHeader(header)
 		chain = append(chain, block)
 	}
 	return chain
@@ -399,7 +401,6 @@ func chm(genesis *types.Block, db common.Database) *ChainManager {
 }
 
 func TestReorgLongest(t *testing.T) {
-	t.Skip("skipped while cache is removed")
 	db, _ := ethdb.NewMemDatabase()
 	genesis := GenesisBlock(0, db)
 	bc := chm(genesis, db)
@@ -419,7 +420,6 @@ func TestReorgLongest(t *testing.T) {
 }
 
 func TestReorgShortest(t *testing.T) {
-	t.Skip("skipped while cache is removed")
 	db, _ := ethdb.NewMemDatabase()
 	genesis := GenesisBlock(0, db)
 	bc := chm(genesis, db)
diff --git a/core/genesis.go b/core/genesis.go
index dd894e0b0f5a1df1b887448d3a2f4fe2ba5d7239..de2eee9db92e9a4158c7c4646f0e2cbda38b432e 100644
--- a/core/genesis.go
+++ b/core/genesis.go
@@ -11,38 +11,18 @@ import (
 	"github.com/ethereum/go-ethereum/params"
 )
 
-/*
- * This is the special genesis block.
- */
-
-var ZeroHash256 = make([]byte, 32)
-var ZeroHash160 = make([]byte, 20)
-var ZeroHash512 = make([]byte, 64)
-
+// GenesisBlock creates a genesis block with the given nonce.
 func GenesisBlock(nonce uint64, db common.Database) *types.Block {
-	genesis := types.NewBlock(common.Hash{}, common.Address{}, common.Hash{}, params.GenesisDifficulty, nonce, nil)
-	genesis.Header().Number = common.Big0
-	genesis.Header().GasLimit = params.GenesisGasLimit
-	genesis.Header().GasUsed = common.Big0
-	genesis.Header().Time = 0
-
-	genesis.Td = common.Big0
-
-	genesis.SetUncles([]*types.Header{})
-	genesis.SetTransactions(types.Transactions{})
-	genesis.SetReceipts(types.Receipts{})
-
 	var accounts map[string]struct {
 		Balance string
 		Code    string
 	}
 	err := json.Unmarshal(GenesisAccounts, &accounts)
 	if err != nil {
-		fmt.Println("enable to decode genesis json data:", err)
+		fmt.Println("unable to decode genesis json data:", err)
 		os.Exit(1)
 	}
-
-	statedb := state.New(genesis.Root(), db)
+	statedb := state.New(common.Hash{}, db)
 	for addr, account := range accounts {
 		codedAddr := common.Hex2Bytes(addr)
 		accountState := statedb.CreateAccount(common.BytesToAddress(codedAddr))
@@ -51,10 +31,15 @@ func GenesisBlock(nonce uint64, db common.Database) *types.Block {
 		statedb.UpdateStateObject(accountState)
 	}
 	statedb.Sync()
-	genesis.Header().Root = statedb.Root()
-	genesis.Td = params.GenesisDifficulty
 
-	return genesis
+	block := types.NewBlock(&types.Header{
+		Difficulty: params.GenesisDifficulty,
+		GasLimit:   params.GenesisGasLimit,
+		Nonce:      types.EncodeNonce(nonce),
+		Root:       statedb.Root(),
+	}, nil, nil, nil)
+	block.Td = params.GenesisDifficulty
+	return block
 }
 
 var GenesisAccounts = []byte(`{
diff --git a/core/state_transition.go b/core/state_transition.go
index 915dd466bce0a8ff927b34147073f6492a2dbf75..2c8770cbe50d2b5cde27a98db7b489fe4fa6c1cb 100644
--- a/core/state_transition.go
+++ b/core/state_transition.go
@@ -73,16 +73,17 @@ func MessageGasValue(msg Message) *big.Int {
 	return new(big.Int).Mul(msg.Gas(), msg.GasPrice())
 }
 
-func IntrinsicGas(msg Message) *big.Int {
+// IntrinsicGas computes the 'intrisic gas' for a message
+// with the given data.
+func IntrinsicGas(data []byte) *big.Int {
 	igas := new(big.Int).Set(params.TxGas)
-	for _, byt := range msg.Data() {
+	for _, byt := range data {
 		if byt != 0 {
 			igas.Add(igas, params.TxDataNonZeroGas)
 		} else {
 			igas.Add(igas, params.TxDataZeroGas)
 		}
 	}
-
 	return igas
 }
 
@@ -195,7 +196,7 @@ func (self *StateTransition) transitionState() (ret []byte, usedGas *big.Int, er
 	sender, _ := self.From() // err checked in preCheck
 
 	// Pay intrinsic gas
-	if err = self.UseGas(IntrinsicGas(self.msg)); err != nil {
+	if err = self.UseGas(IntrinsicGas(self.msg.Data())); err != nil {
 		return nil, nil, InvalidTxError(err)
 	}
 
diff --git a/core/transaction_pool.go b/core/transaction_pool.go
index 45db04eef4268de5f3cb37042f9ba25617baaf1b..bf28647c37867412726284bc67f7f16fa2ce8469 100644
--- a/core/transaction_pool.go
+++ b/core/transaction_pool.go
@@ -180,7 +180,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction) error {
 	}
 
 	// Should supply enough intrinsic gas
-	if tx.Gas().Cmp(IntrinsicGas(tx)) < 0 {
+	if tx.Gas().Cmp(IntrinsicGas(tx.Data())) < 0 {
 		return ErrIntrinsicGas
 	}
 
diff --git a/core/types/block.go b/core/types/block.go
index d7963981ef914af5f7067811dc48275144a18d92..31ea478d43d646230af0552ab78d78c7603c8d13 100644
--- a/core/types/block.go
+++ b/core/types/block.go
@@ -15,71 +15,59 @@ import (
 	"github.com/ethereum/go-ethereum/rlp"
 )
 
-type Header struct {
-	// Hash to the previous block
-	ParentHash common.Hash
-	// Uncles of this block
-	UncleHash common.Hash
-	// The coin base address
-	Coinbase common.Address
-	// Block Trie state
-	Root common.Hash
-	// Tx sha
-	TxHash common.Hash
-	// Receipt sha
-	ReceiptHash common.Hash
-	// Bloom
-	Bloom Bloom
-	// Difficulty for the current block
-	Difficulty *big.Int
-	// The block number
-	Number *big.Int
-	// Gas limit
-	GasLimit *big.Int
-	// Gas used
-	GasUsed *big.Int
-	// Creation time
-	Time uint64
-	// Extra data
-	Extra []byte
-	// Mix digest for quick checking to prevent DOS
-	MixDigest common.Hash
-	// Nonce
-	Nonce [8]byte
-}
+// A BlockNonce is a 64-bit hash which proves (combined with the
+// mix-hash) that a suffcient amount of computation has been carried
+// out on a block.
+type BlockNonce [8]byte
 
-func (self *Header) Hash() common.Hash {
-	return rlpHash(self.rlpData(true))
+func EncodeNonce(i uint64) BlockNonce {
+	var n BlockNonce
+	binary.BigEndian.PutUint64(n[:], i)
+	return n
 }
 
-func (self *Header) HashNoNonce() common.Hash {
-	return rlpHash(self.rlpData(false))
+func (n BlockNonce) Uint64() uint64 {
+	return binary.BigEndian.Uint64(n[:])
 }
 
-func (self *Header) rlpData(withNonce bool) []interface{} {
-	fields := []interface{}{
-		self.ParentHash,
-		self.UncleHash,
-		self.Coinbase,
-		self.Root,
-		self.TxHash,
-		self.ReceiptHash,
-		self.Bloom,
-		self.Difficulty,
-		self.Number,
-		self.GasLimit,
-		self.GasUsed,
-		self.Time,
-		self.Extra,
-	}
-	if withNonce {
-		fields = append(fields, self.MixDigest, self.Nonce)
-	}
-	return fields
-}
-
-func (self *Header) RlpData() interface{} {
-	return self.rlpData(true)
+type Header struct {
+	ParentHash  common.Hash    // Hash to the previous block
+	UncleHash   common.Hash    // Uncles of this block
+	Coinbase    common.Address // The coin base address
+	Root        common.Hash    // Block Trie state
+	TxHash      common.Hash    // Tx sha
+	ReceiptHash common.Hash    // Receipt sha
+	Bloom       Bloom          // Bloom
+	Difficulty  *big.Int       // Difficulty for the current block
+	Number      *big.Int       // The block number
+	GasLimit    *big.Int       // Gas limit
+	GasUsed     *big.Int       // Gas used
+	Time        uint64         // Creation time
+	Extra       []byte         // Extra data
+	MixDigest   common.Hash    // for quick difficulty verification
+	Nonce       BlockNonce
+}
+
+func (h *Header) Hash() common.Hash {
+	return rlpHash(h)
+}
+
+func (h *Header) HashNoNonce() common.Hash {
+	return rlpHash([]interface{}{
+		h.ParentHash,
+		h.UncleHash,
+		h.Coinbase,
+		h.Root,
+		h.TxHash,
+		h.ReceiptHash,
+		h.Bloom,
+		h.Difficulty,
+		h.Number,
+		h.GasLimit,
+		h.GasUsed,
+		h.Time,
+		h.Extra,
+	})
 }
 
 func (h *Header) UnmarshalJSON(data []byte) error {
@@ -112,20 +100,14 @@ func rlpHash(x interface{}) (h common.Hash) {
 }
 
 type Block struct {
-	// Preset Hash for mock (Tests)
-	HeaderHash       common.Hash
-	ParentHeaderHash common.Hash
-	// ^^^^ ignore ^^^^
-
 	header       *Header
 	uncles       []*Header
 	transactions Transactions
-	Td           *big.Int
-	queued       bool // flag for blockpool to skip TD check
+	receipts     Receipts
 
+	Td         *big.Int
+	queued     bool // flag for blockpool to skip TD check
 	ReceivedAt time.Time
-
-	receipts Receipts
 }
 
 // StorageBlock defines the RLP encoding of a Block stored in the
@@ -148,43 +130,90 @@ type storageblock struct {
 	TD     *big.Int
 }
 
-func NewBlock(parentHash common.Hash, coinbase common.Address, root common.Hash, difficulty *big.Int, nonce uint64, extra []byte) *Block {
-	header := &Header{
-		Root:       root,
-		ParentHash: parentHash,
-		Coinbase:   coinbase,
-		Difficulty: difficulty,
-		Time:       uint64(time.Now().Unix()),
-		Extra:      extra,
-		GasUsed:    new(big.Int),
-		GasLimit:   new(big.Int),
-		Number:     new(big.Int),
+var (
+	emptyRootHash  = DeriveSha(Transactions{})
+	emptyUncleHash = CalcUncleHash(nil)
+)
+
+// NewBlock creates a new block. The input data is copied,
+// changes to header and to the field values will not affect the
+// block.
+//
+// The values of TxHash, UncleHash, ReceiptHash and Bloom in header
+// are ignored and set to values derived from the given txs, uncles
+// and receipts.
+func NewBlock(header *Header, txs []*Transaction, uncles []*Header, receipts []*Receipt) *Block {
+	b := &Block{header: copyHeader(header), Td: new(big.Int)}
+
+	// TODO: panic if len(txs) != len(receipts)
+	if len(txs) == 0 {
+		b.header.TxHash = emptyRootHash
+	} else {
+		b.header.TxHash = DeriveSha(Transactions(txs))
+		b.transactions = make(Transactions, len(txs))
+		copy(b.transactions, txs)
 	}
-	header.SetNonce(nonce)
-	block := &Block{header: header}
-	block.Td = new(big.Int)
 
-	return block
-}
+	if len(receipts) == 0 {
+		b.header.ReceiptHash = emptyRootHash
+	} else {
+		b.header.ReceiptHash = DeriveSha(Receipts(receipts))
+		b.header.Bloom = CreateBloom(receipts)
+		b.receipts = make([]*Receipt, len(receipts))
+		copy(b.receipts, receipts)
+	}
 
-func (self *Header) SetNonce(nonce uint64) {
-	binary.BigEndian.PutUint64(self.Nonce[:], nonce)
+	if len(uncles) == 0 {
+		b.header.UncleHash = emptyUncleHash
+	} else {
+		b.header.UncleHash = CalcUncleHash(uncles)
+		b.uncles = make([]*Header, len(uncles))
+		for i := range uncles {
+			b.uncles[i] = copyHeader(uncles[i])
+		}
+	}
+
+	return b
 }
 
+// NewBlockWithHeader creates a block with the given header data. The
+// header data is copied, changes to header and to the field values
+// will not affect the block.
 func NewBlockWithHeader(header *Header) *Block {
-	return &Block{header: header}
+	return &Block{header: copyHeader(header)}
+}
+
+func copyHeader(h *Header) *Header {
+	cpy := *h
+	if cpy.Difficulty = new(big.Int); h.Difficulty != nil {
+		cpy.Difficulty.Set(h.Difficulty)
+	}
+	if cpy.Number = new(big.Int); h.Number != nil {
+		cpy.Number.Set(h.Number)
+	}
+	if cpy.GasLimit = new(big.Int); h.GasLimit != nil {
+		cpy.GasLimit.Set(h.GasLimit)
+	}
+	if cpy.GasUsed = new(big.Int); h.GasUsed != nil {
+		cpy.GasUsed.Set(h.GasUsed)
+	}
+	if len(h.Extra) > 0 {
+		cpy.Extra = make([]byte, len(h.Extra))
+		copy(cpy.Extra, h.Extra)
+	}
+	return &cpy
 }
 
-func (self *Block) ValidateFields() error {
-	if self.header == nil {
+func (b *Block) ValidateFields() error {
+	if b.header == nil {
 		return fmt.Errorf("header is nil")
 	}
-	for i, transaction := range self.transactions {
+	for i, transaction := range b.transactions {
 		if transaction == nil {
 			return fmt.Errorf("transaction %d is nil", i)
 		}
 	}
-	for i, uncle := range self.uncles {
+	for i, uncle := range b.uncles {
 		if uncle == nil {
 			return fmt.Errorf("uncle %d is nil", i)
 		}
@@ -192,64 +221,48 @@ func (self *Block) ValidateFields() error {
 	return nil
 }
 
-func (self *Block) DecodeRLP(s *rlp.Stream) error {
+func (b *Block) DecodeRLP(s *rlp.Stream) error {
 	var eb extblock
 	if err := s.Decode(&eb); err != nil {
 		return err
 	}
-	self.header, self.uncles, self.transactions = eb.Header, eb.Uncles, eb.Txs
+	b.header, b.uncles, b.transactions = eb.Header, eb.Uncles, eb.Txs
 	return nil
 }
 
-func (self Block) EncodeRLP(w io.Writer) error {
+func (b Block) EncodeRLP(w io.Writer) error {
 	return rlp.Encode(w, extblock{
-		Header: self.header,
-		Txs:    self.transactions,
-		Uncles: self.uncles,
+		Header: b.header,
+		Txs:    b.transactions,
+		Uncles: b.uncles,
 	})
 }
 
-func (self *StorageBlock) DecodeRLP(s *rlp.Stream) error {
+func (b *StorageBlock) DecodeRLP(s *rlp.Stream) error {
 	var sb storageblock
 	if err := s.Decode(&sb); err != nil {
 		return err
 	}
-	self.header, self.uncles, self.transactions, self.Td = sb.Header, sb.Uncles, sb.Txs, sb.TD
+	b.header, b.uncles, b.transactions, b.Td = sb.Header, sb.Uncles, sb.Txs, sb.TD
 	return nil
 }
 
-func (self StorageBlock) EncodeRLP(w io.Writer) error {
+func (b StorageBlock) EncodeRLP(w io.Writer) error {
 	return rlp.Encode(w, storageblock{
-		Header: self.header,
-		Txs:    self.transactions,
-		Uncles: self.uncles,
-		TD:     self.Td,
+		Header: b.header,
+		Txs:    b.transactions,
+		Uncles: b.uncles,
+		TD:     b.Td,
 	})
 }
 
-func (self *Block) Header() *Header {
-	return self.header
-}
-
-func (self *Block) Uncles() []*Header {
-	return self.uncles
-}
-
-func (self *Block) CalculateUnclesHash() common.Hash {
-	return rlpHash(self.uncles)
-}
+// TODO: copies
+func (b *Block) Uncles() []*Header          { return b.uncles }
+func (b *Block) Transactions() Transactions { return b.transactions }
+func (b *Block) Receipts() Receipts         { return b.receipts }
 
-func (self *Block) SetUncles(uncleHeaders []*Header) {
-	self.uncles = uncleHeaders
-	self.header.UncleHash = rlpHash(uncleHeaders)
-}
-
-func (self *Block) Transactions() Transactions {
-	return self.transactions
-}
-
-func (self *Block) Transaction(hash common.Hash) *Transaction {
-	for _, transaction := range self.transactions {
+func (b *Block) Transaction(hash common.Hash) *Transaction {
+	for _, transaction := range b.transactions {
 		if transaction.Hash() == hash {
 			return transaction
 		}
@@ -257,74 +270,33 @@ func (self *Block) Transaction(hash common.Hash) *Transaction {
 	return nil
 }
 
-func (self *Block) SetTransactions(transactions Transactions) {
-	self.transactions = transactions
-	self.header.TxHash = DeriveSha(transactions)
-}
-func (self *Block) AddTransaction(transaction *Transaction) {
-	self.transactions = append(self.transactions, transaction)
-	self.SetTransactions(self.transactions)
-}
-
-func (self *Block) Receipts() Receipts {
-	return self.receipts
-}
-
-func (self *Block) SetReceipts(receipts Receipts) {
-	self.receipts = receipts
-	self.header.ReceiptHash = DeriveSha(receipts)
-	self.header.Bloom = CreateBloom(receipts)
-}
-func (self *Block) AddReceipt(receipt *Receipt) {
-	self.receipts = append(self.receipts, receipt)
-	self.SetReceipts(self.receipts)
-}
-
-func (self *Block) RlpData() interface{} {
-	return []interface{}{self.header, self.transactions, self.uncles}
-}
+func (b *Block) Number() *big.Int     { return new(big.Int).Set(b.header.Number) }
+func (b *Block) GasLimit() *big.Int   { return new(big.Int).Set(b.header.GasLimit) }
+func (b *Block) GasUsed() *big.Int    { return new(big.Int).Set(b.header.GasUsed) }
+func (b *Block) Difficulty() *big.Int { return new(big.Int).Set(b.header.Difficulty) }
 
-func (self *Block) RlpDataForStorage() interface{} {
-	return []interface{}{self.header, self.transactions, self.uncles, self.Td /* TODO receipts */}
-}
+func (b *Block) NumberU64() uint64        { return b.header.Number.Uint64() }
+func (b *Block) MixDigest() common.Hash   { return b.header.MixDigest }
+func (b *Block) Nonce() uint64            { return binary.BigEndian.Uint64(b.header.Nonce[:]) }
+func (b *Block) Bloom() Bloom             { return b.header.Bloom }
+func (b *Block) Coinbase() common.Address { return b.header.Coinbase }
+func (b *Block) Time() int64              { return int64(b.header.Time) }
+func (b *Block) Root() common.Hash        { return b.header.Root }
+func (b *Block) ParentHash() common.Hash  { return b.header.ParentHash }
+func (b *Block) TxHash() common.Hash      { return b.header.TxHash }
+func (b *Block) ReceiptHash() common.Hash { return b.header.ReceiptHash }
+func (b *Block) UncleHash() common.Hash   { return b.header.UncleHash }
+func (b *Block) Extra() []byte            { return common.CopyBytes(b.header.Extra) }
 
-// Header accessors (add as you need them)
-func (self *Block) Number() *big.Int       { return self.header.Number }
-func (self *Block) NumberU64() uint64      { return self.header.Number.Uint64() }
-func (self *Block) MixDigest() common.Hash { return self.header.MixDigest }
-func (self *Block) Nonce() uint64 {
-	return binary.BigEndian.Uint64(self.header.Nonce[:])
-}
-func (self *Block) SetNonce(nonce uint64) {
-	self.header.SetNonce(nonce)
-}
+func (b *Block) Header() *Header { return copyHeader(b.header) }
 
-func (self *Block) Queued() bool     { return self.queued }
-func (self *Block) SetQueued(q bool) { self.queued = q }
-
-func (self *Block) Bloom() Bloom             { return self.header.Bloom }
-func (self *Block) Coinbase() common.Address { return self.header.Coinbase }
-func (self *Block) Time() int64              { return int64(self.header.Time) }
-func (self *Block) GasLimit() *big.Int       { return self.header.GasLimit }
-func (self *Block) GasUsed() *big.Int        { return self.header.GasUsed }
-func (self *Block) Root() common.Hash        { return self.header.Root }
-func (self *Block) SetRoot(root common.Hash) { self.header.Root = root }
-func (self *Block) GetTransaction(i int) *Transaction {
-	if len(self.transactions) > i {
-		return self.transactions[i]
-	}
-	return nil
-}
-func (self *Block) GetUncle(i int) *Header {
-	if len(self.uncles) > i {
-		return self.uncles[i]
-	}
-	return nil
+func (b *Block) HashNoNonce() common.Hash {
+	return b.header.HashNoNonce()
 }
 
-func (self *Block) Size() common.StorageSize {
+func (b *Block) Size() common.StorageSize {
 	c := writeCounter(0)
-	rlp.Encode(&c, self)
+	rlp.Encode(&c, b)
 	return common.StorageSize(c)
 }
 
@@ -335,48 +307,32 @@ func (c *writeCounter) Write(b []byte) (int, error) {
 	return len(b), nil
 }
 
-// Implement pow.Block
-func (self *Block) Difficulty() *big.Int     { return self.header.Difficulty }
-func (self *Block) HashNoNonce() common.Hash { return self.header.HashNoNonce() }
-
-func (self *Block) Hash() common.Hash {
-	if (self.HeaderHash != common.Hash{}) {
-		return self.HeaderHash
-	} else {
-		return self.header.Hash()
-	}
+func CalcUncleHash(uncles []*Header) common.Hash {
+	return rlpHash(uncles)
 }
 
-func (self *Block) ParentHash() common.Hash {
-	if (self.ParentHeaderHash != common.Hash{}) {
-		return self.ParentHeaderHash
-	} else {
-		return self.header.ParentHash
+// WithMiningResult returns a new block with the data from b
+// where nonce and mix digest are set to the provided values.
+func (b *Block) WithMiningResult(nonce uint64, mixDigest common.Hash) *Block {
+	cpy := *b.header
+	binary.BigEndian.PutUint64(cpy.Nonce[:], nonce)
+	cpy.MixDigest = mixDigest
+	return &Block{
+		header:       &cpy,
+		transactions: b.transactions,
+		receipts:     b.receipts,
+		uncles:       b.uncles,
+		Td:           b.Td,
 	}
 }
 
-func (self *Block) Copy() *Block {
-	block := NewBlock(self.header.ParentHash, self.Coinbase(), self.Root(), new(big.Int), self.Nonce(), self.header.Extra)
-	block.header.Bloom = self.header.Bloom
-	block.header.TxHash = self.header.TxHash
-	block.transactions = self.transactions
-	block.header.UncleHash = self.header.UncleHash
-	block.uncles = self.uncles
-	block.header.GasLimit.Set(self.header.GasLimit)
-	block.header.GasUsed.Set(self.header.GasUsed)
-	block.header.ReceiptHash = self.header.ReceiptHash
-	block.header.Difficulty.Set(self.header.Difficulty)
-	block.header.Number.Set(self.header.Number)
-	block.header.Time = self.header.Time
-	block.header.MixDigest = self.header.MixDigest
-	if self.Td != nil {
-		block.Td.Set(self.Td)
-	}
+// Implement pow.Block
 
-	return block
+func (b *Block) Hash() common.Hash {
+	return b.header.Hash()
 }
 
-func (self *Block) String() string {
+func (b *Block) String() string {
 	str := fmt.Sprintf(`Block(#%v): Size: %v TD: %v {
 MinerHash: %x
 %v
@@ -385,20 +341,11 @@ Transactions:
 Uncles:
 %v
 }
-`, self.Number(), self.Size(), self.Td, self.header.HashNoNonce(), self.header, self.transactions, self.uncles)
-
-	if (self.HeaderHash != common.Hash{}) {
-		str += fmt.Sprintf("\nFake hash = %x", self.HeaderHash)
-	}
-
-	if (self.ParentHeaderHash != common.Hash{}) {
-		str += fmt.Sprintf("\nFake parent hash = %x", self.ParentHeaderHash)
-	}
-
+`, b.Number(), b.Size(), b.Td, b.header.HashNoNonce(), b.header, b.transactions, b.uncles)
 	return str
 }
 
-func (self *Header) String() string {
+func (h *Header) String() string {
 	return fmt.Sprintf(`Header(%x):
 [
 	ParentHash:	    %x
@@ -414,9 +361,9 @@ func (self *Header) String() string {
 	GasUsed:	    %v
 	Time:		    %v
 	Extra:		    %s
-	MixDigest:          %x
+	MixDigest:      %x
 	Nonce:		    %x
-]`, self.Hash(), self.ParentHash, self.UncleHash, self.Coinbase, self.Root, self.TxHash, self.ReceiptHash, self.Bloom, self.Difficulty, self.Number, self.GasLimit, self.GasUsed, self.Time, self.Extra, self.MixDigest, self.Nonce)
+]`, h.Hash(), h.ParentHash, h.UncleHash, h.Coinbase, h.Root, h.TxHash, h.ReceiptHash, h.Bloom, h.Difficulty, h.Number, h.GasLimit, h.GasUsed, h.Time, h.Extra, h.MixDigest, h.Nonce)
 }
 
 type Blocks []*Block
@@ -442,4 +389,4 @@ func (self blockSorter) Swap(i, j int) {
 }
 func (self blockSorter) Less(i, j int) bool { return self.by(self.blocks[i], self.blocks[j]) }
 
-func Number(b1, b2 *Block) bool { return b1.Header().Number.Cmp(b2.Header().Number) < 0 }
+func Number(b1, b2 *Block) bool { return b1.header.Number.Cmp(b2.header.Number) < 0 }
diff --git a/core/vm_env.go b/core/vm_env.go
index da862d5c8c98c3d0fd292a92e2e26fabbbbf553e..6dd83acde0d43bc89aefd7491de9786ba28c16db 100644
--- a/core/vm_env.go
+++ b/core/vm_env.go
@@ -10,32 +10,32 @@ import (
 )
 
 type VMEnv struct {
-	state *state.StateDB
-	block *types.Block
-	msg   Message
-	depth int
-	chain *ChainManager
-	typ   vm.Type
+	state  *state.StateDB
+	header *types.Header
+	msg    Message
+	depth  int
+	chain  *ChainManager
+	typ    vm.Type
 	// structured logging
 	logs []vm.StructLog
 }
 
-func NewEnv(state *state.StateDB, chain *ChainManager, msg Message, block *types.Block) *VMEnv {
+func NewEnv(state *state.StateDB, chain *ChainManager, msg Message, header *types.Header) *VMEnv {
 	return &VMEnv{
-		chain: chain,
-		state: state,
-		block: block,
-		msg:   msg,
-		typ:   vm.StdVmTy,
+		chain:  chain,
+		state:  state,
+		header: header,
+		msg:    msg,
+		typ:    vm.StdVmTy,
 	}
 }
 
 func (self *VMEnv) Origin() common.Address   { f, _ := self.msg.From(); return f }
-func (self *VMEnv) BlockNumber() *big.Int    { return self.block.Number() }
-func (self *VMEnv) Coinbase() common.Address { return self.block.Coinbase() }
-func (self *VMEnv) Time() int64              { return self.block.Time() }
-func (self *VMEnv) Difficulty() *big.Int     { return self.block.Difficulty() }
-func (self *VMEnv) GasLimit() *big.Int       { return self.block.GasLimit() }
+func (self *VMEnv) BlockNumber() *big.Int    { return self.header.Number }
+func (self *VMEnv) Coinbase() common.Address { return self.header.Coinbase }
+func (self *VMEnv) Time() int64              { return int64(self.header.Time) }
+func (self *VMEnv) Difficulty() *big.Int     { return self.header.Difficulty }
+func (self *VMEnv) GasLimit() *big.Int       { return self.header.GasLimit }
 func (self *VMEnv) Value() *big.Int          { return self.msg.Value() }
 func (self *VMEnv) State() *state.StateDB    { return self.state }
 func (self *VMEnv) Depth() int               { return self.depth }
diff --git a/eth/downloader/downloader_test.go b/eth/downloader/downloader_test.go
index 4fc4e1434d88651cdb145db70055e9c85770d018..fb8aa7e4b5dbfad943f5dea6817b797dce95335f 100644
--- a/eth/downloader/downloader_test.go
+++ b/eth/downloader/downloader_test.go
@@ -40,7 +40,10 @@ func createHashes(amount int, root common.Hash) (hashes []common.Hash) {
 
 // createBlock assembles a new block at the given chain height.
 func createBlock(i int, parent, hash common.Hash) *types.Block {
-	header := &types.Header{Number: big.NewInt(int64(i))}
+	header := &types.Header{
+		Hash: hash,
+		Number: big.NewInt(int64(i))
+	}
 	block := types.NewBlockWithHeader(header)
 	block.HeaderHash = hash
 	block.ParentHeaderHash = parent
diff --git a/miner/agent.go b/miner/agent.go
index 3ed3ba839ef153cf341be08bcec9e60dba29b7ed..a7d017aa5e17a5f1cdc76c27baf2e552db763f44 100644
--- a/miner/agent.go
+++ b/miner/agent.go
@@ -90,15 +90,13 @@ done:
 	}
 }
 
-func (self *CpuAgent) mine(block *types.Block, stop <- chan struct{}) {
+func (self *CpuAgent) mine(block *types.Block, stop <-chan struct{}) {
 	glog.V(logger.Debug).Infof("(re)started agent[%d]. mining...\n", self.index)
 
 	// Mine
 	nonce, mixDigest := self.pow.Search(block, stop)
 	if nonce != 0 {
-		block.SetNonce(nonce)
-		block.Header().MixDigest = common.BytesToHash(mixDigest)
-		self.returnCh <- block
+		self.returnCh <- block.WithMiningResult(nonce, common.BytesToHash(mixDigest))
 	} else {
 		self.returnCh <- nil
 	}
diff --git a/miner/remote_agent.go b/miner/remote_agent.go
index 80cc9053e1d518bb9e09c2aa22f2c450a0e346db..6a44782f6d4cb292ed6551a0001d44b6ecc8c882 100644
--- a/miner/remote_agent.go
+++ b/miner/remote_agent.go
@@ -81,9 +81,7 @@ func (a *RemoteAgent) SubmitWork(nonce uint64, mixDigest, seedHash common.Hash)
 
 	// Make sure the external miner was working on the right hash
 	if a.currentWork != nil && a.work != nil {
-		a.currentWork.SetNonce(nonce)
-		a.currentWork.Header().MixDigest = mixDigest
-		a.returnCh <- a.currentWork
+		a.returnCh <- a.currentWork.WithMiningResult(nonce, mixDigest)
 		//a.returnCh <- Work{a.currentWork.Number().Uint64(), nonce, mixDigest.Bytes(), seedHash.Bytes()}
 		return true
 	}
diff --git a/miner/worker.go b/miner/worker.go
index 55c23376cd74b89340ca6835714bfebc0837773a..3a2d7a41b1d55c2cbcd3f4fbc9e5efe05efbe54e 100644
--- a/miner/worker.go
+++ b/miner/worker.go
@@ -49,10 +49,8 @@ type uint64RingBuffer struct {
 // environment is the workers current environment and holds
 // all of the current state information
 type environment struct {
-	totalUsedGas       *big.Int           // total gas usage in the cycle
 	state              *state.StateDB     // apply state changes here
 	coinbase           *state.StateObject // the miner's account
-	block              *types.Block       // the new block
 	ancestors          *set.Set           // ancestor set (used for checking uncle parent validity)
 	family             *set.Set           // family set (used for checking uncle invalidity)
 	uncles             *set.Set           // uncle set
@@ -63,22 +61,12 @@ type environment struct {
 	ownedAccounts      *set.Set
 	lowGasTxs          types.Transactions
 	localMinedBlocks   *uint64RingBuffer // the most recent block numbers that were mined locally (used to check block inclusion)
-}
 
-// env returns a new environment for the current cycle
-func env(block *types.Block, eth core.Backend) *environment {
-	state := state.New(block.Root(), eth.StateDb())
-	env := &environment{
-		totalUsedGas: new(big.Int),
-		state:        state,
-		block:        block,
-		ancestors:    set.New(),
-		family:       set.New(),
-		uncles:       set.New(),
-		coinbase:     state.GetOrNewStateObject(block.Coinbase()),
-	}
+	block *types.Block // the new block
 
-	return env
+	header   *types.Header
+	txs      []*types.Transaction
+	receipts []*types.Receipt
 }
 
 // worker is the main object which takes care of applying messages to the new state
@@ -137,14 +125,20 @@ func newWorker(coinbase common.Address, eth core.Backend) *worker {
 func (self *worker) pendingState() *state.StateDB {
 	self.currentMu.Lock()
 	defer self.currentMu.Unlock()
-
 	return self.current.state
 }
 
 func (self *worker) pendingBlock() *types.Block {
 	self.currentMu.Lock()
 	defer self.currentMu.Unlock()
-
+	if atomic.LoadInt32(&self.mining) == 0 {
+		return types.NewBlock(
+			self.current.header,
+			self.current.txs,
+			nil,
+			self.current.receipts,
+		)
+	}
 	return self.current.block
 }
 
@@ -206,7 +200,7 @@ out:
 				// Apply transaction to the pending state if we're not mining
 				if atomic.LoadInt32(&self.mining) == 0 {
 					self.mu.Lock()
-					self.commitTransactions(types.Transactions{ev.Tx})
+					self.current.commitTransactions(types.Transactions{ev.Tx}, self.gasPrice, self.proc)
 					self.mu.Unlock()
 				}
 			}
@@ -259,8 +253,8 @@ func (self *worker) wait() {
 				jsonlogger.LogJson(&logger.EthMinerNewBlock{
 					BlockHash:     block.Hash().Hex(),
 					BlockNumber:   block.Number(),
-					ChainHeadHash: block.ParentHeaderHash.Hex(),
-					BlockPrevHash: block.ParentHeaderHash.Hex(),
+					ChainHeadHash: block.ParentHash().Hex(),
+					BlockPrevHash: block.ParentHash().Hex(),
 				})
 			} else {
 				self.commitNewWork()
@@ -271,14 +265,12 @@ func (self *worker) wait() {
 
 func (self *worker) push() {
 	if atomic.LoadInt32(&self.mining) == 1 {
-		self.current.block.SetRoot(self.current.state.Root())
-
 		// push new work to agents
 		for _, agent := range self.agents {
 			atomic.AddInt32(&self.atWork, 1)
 
 			if agent.Work() != nil {
-				agent.Work() <- self.current.block.Copy()
+				agent.Work() <- self.current.block
 			} else {
 				common.Report(fmt.Sprintf("%v %T\n", agent, agent))
 			}
@@ -286,22 +278,20 @@ func (self *worker) push() {
 	}
 }
 
-func (self *worker) makeCurrent() {
-	block := self.chain.NewBlock(self.coinbase)
-	parent := self.chain.GetBlock(block.ParentHash())
-	// TMP fix for build server ...
-	if parent == nil {
-		return
-	}
-
-	if block.Time() <= parent.Time() {
-		block.Header().Time = parent.Header().Time + 1
+// makeCurrent creates a new environment for the current cycle.
+func (self *worker) makeCurrent(parent *types.Block, header *types.Header) {
+	state := state.New(parent.Root(), self.eth.StateDb())
+	current := &environment{
+		state:     state,
+		ancestors: set.New(),
+		family:    set.New(),
+		uncles:    set.New(),
+		header:    header,
+		coinbase:  state.GetOrNewStateObject(self.coinbase),
 	}
-	block.Header().Extra = self.extra
 
 	// when 08 is processed ancestors contain 07 (quick block)
-	current := env(block, self.eth)
-	for _, ancestor := range self.chain.GetAncestors(block, 7) {
+	for _, ancestor := range self.chain.GetBlocksFromHash(parent.Hash(), 7) {
 		for _, uncle := range ancestor.Uncles() {
 			current.family.Add(uncle.Hash())
 		}
@@ -309,6 +299,7 @@ func (self *worker) makeCurrent() {
 		current.ancestors.Add(ancestor.Hash())
 	}
 	accounts, _ := self.eth.AccountManager().Accounts()
+
 	// Keep track of transactions which return errors so they can be removed
 	current.remove = set.New()
 	current.tcount = 0
@@ -318,9 +309,6 @@ func (self *worker) makeCurrent() {
 	if self.current != nil {
 		current.localMinedBlocks = self.current.localMinedBlocks
 	}
-
-	current.coinbase.SetGasLimit(core.CalcGasLimit(parent))
-
 	self.current = current
 }
 
@@ -352,13 +340,13 @@ func (self *worker) isBlockLocallyMined(deepBlockNum uint64) bool {
 
 	//Does the block at {deepBlockNum} send earnings to my coinbase?
 	var block = self.chain.GetBlockByNumber(deepBlockNum)
-	return block != nil && block.Header().Coinbase == self.coinbase
+	return block != nil && block.Coinbase() == self.coinbase
 }
 
 func (self *worker) logLocalMinedBlocks(previous *environment) {
 	if previous != nil && self.current.localMinedBlocks != nil {
-		nextBlockNum := self.current.block.Number().Uint64()
-		for checkBlockNum := previous.block.Number().Uint64(); checkBlockNum < nextBlockNum; checkBlockNum++ {
+		nextBlockNum := self.current.block.NumberU64()
+		for checkBlockNum := previous.block.NumberU64(); checkBlockNum < nextBlockNum; checkBlockNum++ {
 			inspectBlockNum := checkBlockNum - miningLogAtDepth
 			if self.isBlockLocallyMined(inspectBlockNum) {
 				glog.V(logger.Info).Infof("🔨 🔗  Mined %d blocks back: block #%v", miningLogAtDepth, inspectBlockNum)
@@ -376,18 +364,35 @@ func (self *worker) commitNewWork() {
 	defer self.currentMu.Unlock()
 
 	tstart := time.Now()
+	parent := self.chain.CurrentBlock()
+	tstamp := tstart.Unix()
+	if tstamp <= parent.Time() {
+		tstamp = parent.Time() + 1
+	}
+	num := parent.Number()
+	header := &types.Header{
+		ParentHash: parent.Hash(),
+		Number:     num.Add(num, common.Big1),
+		Difficulty: core.CalcDifficulty(tstamp, parent.Time(), parent.Difficulty()),
+		GasLimit:   core.CalcGasLimit(parent),
+		GasUsed:    new(big.Int),
+		Coinbase:   self.coinbase,
+		Extra:      self.extra,
+		Time:       uint64(tstamp),
+	}
 
 	previous := self.current
-	self.makeCurrent()
+	self.makeCurrent(parent, header)
 	current := self.current
 
+	// commit transactions for this run.
 	transactions := self.eth.TxPool().GetTransactions()
 	sort.Sort(types.TxByNonce{transactions})
-
-	// commit transactions for this run
-	self.commitTransactions(transactions)
+	current.coinbase.SetGasLimit(header.GasLimit)
+	current.commitTransactions(transactions, self.gasPrice, self.proc)
 	self.eth.TxPool().RemoveTransactions(current.lowGasTxs)
 
+	// compute uncles for the new block.
 	var (
 		uncles    []*types.Header
 		badUncles []common.Hash
@@ -396,88 +401,76 @@ func (self *worker) commitNewWork() {
 		if len(uncles) == 2 {
 			break
 		}
-
 		if err := self.commitUncle(uncle.Header()); err != nil {
 			if glog.V(logger.Ridiculousness) {
 				glog.V(logger.Detail).Infof("Bad uncle found and will be removed (%x)\n", hash[:4])
 				glog.V(logger.Detail).Infoln(uncle)
 			}
-
 			badUncles = append(badUncles, hash)
 		} else {
 			glog.V(logger.Debug).Infof("commiting %x as uncle\n", hash[:4])
 			uncles = append(uncles, uncle.Header())
 		}
 	}
-
-	// We only care about logging if we're actually mining
-	if atomic.LoadInt32(&self.mining) == 1 {
-		glog.V(logger.Info).Infof("commit new work on block %v with %d txs & %d uncles. Took %v\n", current.block.Number(), current.tcount, len(uncles), time.Since(tstart))
-		self.logLocalMinedBlocks(previous)
-	}
-
 	for _, hash := range badUncles {
 		delete(self.possibleUncles, hash)
 	}
 
-	self.current.block.SetUncles(uncles)
+	// commit state root after all state transitions.
+	core.AccumulateRewards(self.current.state, header, uncles)
+	current.state.Update()
+	header.Root = current.state.Root()
 
-	core.AccumulateRewards(self.current.state, self.current.block)
+	// create the new block whose nonce will be mined.
+	current.block = types.NewBlock(header, current.txs, uncles, current.receipts)
 
-	self.current.state.Update()
+	// We only care about logging if we're actually mining.
+	if atomic.LoadInt32(&self.mining) == 1 {
+		glog.V(logger.Info).Infof("commit new work on block %v with %d txs & %d uncles. Took %v\n", current.block.Number(), current.tcount, len(uncles), time.Since(tstart))
+		self.logLocalMinedBlocks(previous)
+	}
 
 	self.push()
 }
 
-var (
-	inclusionReward = new(big.Int).Div(core.BlockReward, big.NewInt(32))
-	_uncleReward    = new(big.Int).Mul(core.BlockReward, big.NewInt(15))
-	uncleReward     = new(big.Int).Div(_uncleReward, big.NewInt(16))
-)
-
 func (self *worker) commitUncle(uncle *types.Header) error {
-	if self.current.uncles.Has(uncle.Hash()) {
-		// Error not unique
+	hash := uncle.Hash()
+	if self.current.uncles.Has(hash) {
 		return core.UncleError("Uncle not unique")
 	}
-
 	if !self.current.ancestors.Has(uncle.ParentHash) {
 		return core.UncleError(fmt.Sprintf("Uncle's parent unknown (%x)", uncle.ParentHash[0:4]))
 	}
-
-	if self.current.family.Has(uncle.Hash()) {
-		return core.UncleError(fmt.Sprintf("Uncle already in family (%x)", uncle.Hash()))
+	if self.current.family.Has(hash) {
+		return core.UncleError(fmt.Sprintf("Uncle already in family (%x)", hash))
 	}
 	self.current.uncles.Add(uncle.Hash())
-
 	return nil
 }
 
-func (self *worker) commitTransactions(transactions types.Transactions) {
-	current := self.current
-
+func (env *environment) commitTransactions(transactions types.Transactions, gasPrice *big.Int, proc *core.BlockProcessor) {
 	for _, tx := range transactions {
 		// We can skip err. It has already been validated in the tx pool
 		from, _ := tx.From()
 
 		// Check if it falls within margin. Txs from owned accounts are always processed.
-		if tx.GasPrice().Cmp(self.gasPrice) < 0 && !current.ownedAccounts.Has(from) {
+		if tx.GasPrice().Cmp(gasPrice) < 0 && !env.ownedAccounts.Has(from) {
 			// ignore the transaction and transactor. We ignore the transactor
 			// because nonce will fail after ignoring this transaction so there's
 			// no point
-			current.lowGasTransactors.Add(from)
+			env.lowGasTransactors.Add(from)
 
-			glog.V(logger.Info).Infof("transaction(%x) below gas price (tx=%v ask=%v). All sequential txs from this address(%x) will be ignored\n", tx.Hash().Bytes()[:4], common.CurrencyToString(tx.GasPrice()), common.CurrencyToString(self.gasPrice), from[:4])
+			glog.V(logger.Info).Infof("transaction(%x) below gas price (tx=%v ask=%v). All sequential txs from this address(%x) will be ignored\n", tx.Hash().Bytes()[:4], common.CurrencyToString(tx.GasPrice()), common.CurrencyToString(gasPrice), from[:4])
 		}
 
 		// Continue with the next transaction if the transaction sender is included in
 		// the low gas tx set. This will also remove the tx and all sequential transaction
 		// from this transactor
-		if current.lowGasTransactors.Has(from) {
+		if env.lowGasTransactors.Has(from) {
 			// add tx to the low gas set. This will be removed at the end of the run
 			// owned accounts are ignored
-			if !current.ownedAccounts.Has(from) {
-				current.lowGasTxs = append(current.lowGasTxs, tx)
+			if !env.ownedAccounts.Has(from) {
+				env.lowGasTxs = append(env.lowGasTxs, tx)
 			}
 			continue
 		}
@@ -487,46 +480,41 @@ func (self *worker) commitTransactions(transactions types.Transactions) {
 		// the transaction is processed (that could potentially be included in the block) it
 		// will throw a nonce error because the previous transaction hasn't been processed.
 		// Therefor we need to ignore any transaction after the ignored one.
-		if current.ignoredTransactors.Has(from) {
+		if env.ignoredTransactors.Has(from) {
 			continue
 		}
 
-		self.current.state.StartRecord(tx.Hash(), common.Hash{}, 0)
+		env.state.StartRecord(tx.Hash(), common.Hash{}, 0)
 
-		err := self.commitTransaction(tx)
+		err := env.commitTransaction(tx, proc)
 		switch {
 		case core.IsNonceErr(err) || core.IsInvalidTxErr(err):
-			current.remove.Add(tx.Hash())
+			env.remove.Add(tx.Hash())
 
 			if glog.V(logger.Detail) {
 				glog.Infof("TX (%x) failed, will be removed: %v\n", tx.Hash().Bytes()[:4], err)
 			}
 		case state.IsGasLimitErr(err):
-			from, _ := tx.From()
 			// ignore the transactor so no nonce errors will be thrown for this account
 			// next time the worker is run, they'll be picked up again.
-			current.ignoredTransactors.Add(from)
+			env.ignoredTransactors.Add(from)
 
 			glog.V(logger.Detail).Infof("Gas limit reached for (%x) in this block. Continue to try smaller txs\n", from[:4])
 		default:
-			current.tcount++
+			env.tcount++
 		}
 	}
-
-	self.current.block.Header().GasUsed = self.current.totalUsedGas
 }
 
-func (self *worker) commitTransaction(tx *types.Transaction) error {
-	snap := self.current.state.Copy()
-	receipt, _, err := self.proc.ApplyTransaction(self.current.coinbase, self.current.state, self.current.block, tx, self.current.totalUsedGas, true)
+func (env *environment) commitTransaction(tx *types.Transaction, proc *core.BlockProcessor) error {
+	snap := env.state.Copy()
+	receipt, _, err := proc.ApplyTransaction(env.coinbase, env.state, env.header, tx, env.header.GasUsed, true)
 	if err != nil && (core.IsNonceErr(err) || state.IsGasLimitErr(err) || core.IsInvalidTxErr(err)) {
-		self.current.state.Set(snap)
+		env.state.Set(snap)
 		return err
 	}
-
-	self.current.block.AddTransaction(tx)
-	self.current.block.AddReceipt(receipt)
-
+	env.txs = append(env.txs, tx)
+	env.receipts = append(env.receipts, receipt)
 	return nil
 }
 
diff --git a/tests/block_test_util.go b/tests/block_test_util.go
index 5fdc6402e06805d044715e5171b78805194d3b58..450ef86a170ee0404d0698729891d5bd99aadec4 100644
--- a/tests/block_test_util.go
+++ b/tests/block_test_util.go
@@ -245,7 +245,7 @@ func (t *BlockTest) TryBlocksInsert(chainManager *core.ChainManager) error {
 			if b.BlockHeader == nil {
 				continue // OK - block is supposed to be invalid, continue with next block
 			} else {
-				return fmt.Errorf("Block RLP decoding failed when expected to succeed: ", err)
+				return fmt.Errorf("Block RLP decoding failed when expected to succeed: %v", err)
 			}
 		}
 		// RLP decoding worked, try to insert into chain:
@@ -254,7 +254,7 @@ func (t *BlockTest) TryBlocksInsert(chainManager *core.ChainManager) error {
 			if b.BlockHeader == nil {
 				continue // OK - block is supposed to be invalid, continue with next block
 			} else {
-				return fmt.Errorf("Block insertion into chain failed: ", err)
+				return fmt.Errorf("Block insertion into chain failed: %v", err)
 			}
 		}
 		if b.BlockHeader == nil {
@@ -262,7 +262,7 @@ func (t *BlockTest) TryBlocksInsert(chainManager *core.ChainManager) error {
 		}
 		err = t.validateBlockHeader(b.BlockHeader, cb.Header())
 		if err != nil {
-			return fmt.Errorf("Block header validation failed: ", err)
+			return fmt.Errorf("Block header validation failed: %v", err)
 		}
 	}
 	return nil
@@ -286,7 +286,7 @@ func (s *BlockTest) validateBlockHeader(h *btHeader, h2 *types.Header) error {
 
 	expectedNonce := mustConvertBytes(h.Nonce)
 	if !bytes.Equal(expectedNonce, h2.Nonce[:]) {
-		return fmt.Errorf("Nonce: expected: %v, decoded: %v", expectedNonce, h2.Nonce[:])
+		return fmt.Errorf("Nonce: expected: %v, decoded: %v", expectedNonce, h2.Nonce)
 	}
 
 	expectedNumber := mustConvertBigInt(h.Number, 16)
@@ -423,9 +423,8 @@ func mustConvertHeader(in btHeader) *types.Header {
 		GasLimit:    mustConvertBigInt(in.GasLimit, 16),
 		Difficulty:  mustConvertBigInt(in.Difficulty, 16),
 		Time:        mustConvertUint(in.Timestamp, 16),
+		Nonce:       types.EncodeNonce(mustConvertUint(in.Nonce, 16)),
 	}
-	// XXX cheats? :-)
-	header.SetNonce(mustConvertUint(in.Nonce, 16))
 	return header
 }
 
diff --git a/xeth/xeth.go b/xeth/xeth.go
index 11d30ebaca6e81febb45a6be5b5f4a2a10def211..0dbedff43e368381708ccedd237bf6f26324cc4b 100644
--- a/xeth/xeth.go
+++ b/xeth/xeth.go
@@ -209,8 +209,8 @@ func (self *XEth) AtStateNum(num int64) *XEth {
 // - could be removed in favour of mining on testdag (natspec e2e + networking)
 // + filters
 func (self *XEth) ApplyTestTxs(statedb *state.StateDB, address common.Address, txc uint64) (uint64, *XEth) {
-
-	block := self.backend.ChainManager().NewBlock(address)
+	chain := self.backend.ChainManager()
+	header := chain.CurrentBlock().Header()
 	coinbase := statedb.GetStateObject(address)
 	coinbase.SetGasLimit(big.NewInt(10000000))
 	txs := self.backend.TxPool().GetQueuedTransactions()
@@ -218,7 +218,7 @@ func (self *XEth) ApplyTestTxs(statedb *state.StateDB, address common.Address, t
 	for i := 0; i < len(txs); i++ {
 		for _, tx := range txs {
 			if tx.Nonce() == txc {
-				_, _, err := core.ApplyMessage(core.NewEnv(statedb, self.backend.ChainManager(), tx, block), tx, coinbase)
+				_, _, err := core.ApplyMessage(core.NewEnv(statedb, self.backend.ChainManager(), tx, header), tx, coinbase)
 				if err != nil {
 					panic(err)
 				}
@@ -845,8 +845,8 @@ func (self *XEth) Call(fromStr, toStr, valueStr, gasStr, gasPriceStr, dataStr st
 		msg.gasPrice = self.DefaultGasPrice()
 	}
 
-	block := self.CurrentBlock()
-	vmenv := core.NewEnv(statedb, self.backend.ChainManager(), msg, block)
+	header := self.CurrentBlock().Header()
+	vmenv := core.NewEnv(statedb, self.backend.ChainManager(), msg, header)
 
 	res, gas, err := core.ApplyMessage(vmenv, msg, from)
 	return common.ToHex(res), gas.String(), err