all: refactor so NewBlock, WithBody take types.Body (#29482)

* all: refactor so NewBlock(..) and WithBody(..) take a types.Body

* core: fixup comments, remove txs != receipts panic

* core/types: add empty withdrawls to body if len == 0
This commit is contained in:
lightclient 2024-04-30 06:55:08 -06:00 committed by GitHub
parent 5e07054589
commit 2e8e35f2ad
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 81 additions and 76 deletions

@ -250,7 +250,7 @@ func ExecutableDataToBlock(params ExecutableData, versionedHashes []common.Hash,
BlobGasUsed: params.BlobGasUsed, BlobGasUsed: params.BlobGasUsed,
ParentBeaconRoot: beaconRoot, ParentBeaconRoot: beaconRoot,
} }
block := types.NewBlockWithHeader(header).WithBody(txs, nil /* uncles */).WithWithdrawals(params.Withdrawals) block := types.NewBlockWithHeader(header).WithBody(types.Body{Transactions: txs, Uncles: nil, Withdrawals: params.Withdrawals})
if block.Hash() != params.BlockHash { if block.Hash() != params.BlockHash {
return nil, fmt.Errorf("blockhash mismatch, want %x, got %x", params.BlockHash, block.Hash()) return nil, fmt.Errorf("blockhash mismatch, want %x, got %x", params.BlockHash, block.Hash())
} }

@ -63,9 +63,7 @@ func convertPayload[T payloadType](payload T, parentRoot *zrntcommon.Root) (*typ
panic("unsupported block type") panic("unsupported block type")
} }
block := types.NewBlockWithHeader(&header) block := types.NewBlockWithHeader(&header).WithBody(types.Body{Transactions: transactions, Withdrawals: withdrawals})
block = block.WithBody(transactions, nil)
block = block.WithWithdrawals(withdrawals)
if hash := block.Hash(); hash != expectedHash { if hash := block.Hash(); hash != expectedHash {
return nil, fmt.Errorf("Sanity check failed, payload hash does not match (expected %x, got %x)", expectedHash, hash) return nil, fmt.Errorf("Sanity check failed, payload hash does not match (expected %x, got %x)", expectedHash, hash)
} }

@ -160,7 +160,7 @@ func (i *bbInput) ToBlock() *types.Block {
if i.Header.Difficulty != nil { if i.Header.Difficulty != nil {
header.Difficulty = i.Header.Difficulty header.Difficulty = i.Header.Difficulty
} }
return types.NewBlockWithHeader(header).WithBody(i.Txs, i.Ommers).WithWithdrawals(i.Withdrawals) return types.NewBlockWithHeader(header).WithBody(types.Body{Transactions: i.Txs, Uncles: i.Ommers, Withdrawals: i.Withdrawals})
} }
// SealBlock seals the given block using the configured engine. // SealBlock seals the given block using the configured engine.

@ -388,7 +388,7 @@ func (beacon *Beacon) FinalizeAndAssemble(chain consensus.ChainHeaderReader, hea
header.Root = state.IntermediateRoot(true) header.Root = state.IntermediateRoot(true)
// Assemble and return the final block. // Assemble and return the final block.
return types.NewBlockWithWithdrawals(header, body.Transactions, body.Uncles, receipts, body.Withdrawals, trie.NewStackTrie(nil)), nil return types.NewBlock(header, body, receipts, trie.NewStackTrie(nil)), nil
} }
// Seal generates a new sealing request for the given input block and pushes // Seal generates a new sealing request for the given input block and pushes

@ -597,7 +597,7 @@ func (c *Clique) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
// Assemble and return the final block for sealing. // Assemble and return the final block for sealing.
return types.NewBlock(header, body.Transactions, nil, receipts, trie.NewStackTrie(nil)), nil return types.NewBlock(header, &types.Body{Transactions: body.Transactions}, receipts, trie.NewStackTrie(nil)), nil
} }
// Authorize injects a private key into the consensus engine to mint new blocks // Authorize injects a private key into the consensus engine to mint new blocks

@ -520,7 +520,7 @@ func (ethash *Ethash) FinalizeAndAssemble(chain consensus.ChainHeaderReader, hea
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
// Header seems complete, assemble into a block and return // Header seems complete, assemble into a block and return
return types.NewBlock(header, body.Transactions, body.Uncles, receipts, trie.NewStackTrie(nil)), nil return types.NewBlock(header, &types.Body{Transactions: body.Transactions, Uncles: body.Uncles}, receipts, trie.NewStackTrie(nil)), nil
} }
// SealHash returns the hash of a block prior to it being sealed. // SealHash returns the hash of a block prior to it being sealed.

@ -476,7 +476,7 @@ func (g *Genesis) ToBlock() *types.Block {
} }
} }
} }
return types.NewBlock(head, nil, nil, nil, trie.NewStackTrie(nil)).WithWithdrawals(withdrawals) return types.NewBlock(head, &types.Body{Withdrawals: withdrawals}, nil, trie.NewStackTrie(nil))
} }
// Commit writes the block and state of a genesis specification to the database. // Commit writes the block and state of a genesis specification to the database.

@ -753,7 +753,7 @@ func ReadBlock(db ethdb.Reader, hash common.Hash, number uint64) *types.Block {
if body == nil { if body == nil {
return nil return nil
} }
return types.NewBlockWithHeader(header).WithBody(body.Transactions, body.Uncles).WithWithdrawals(body.Withdrawals) return types.NewBlockWithHeader(header).WithBody(*body)
} }
// WriteBlock serializes a block into the database, header and body separately. // WriteBlock serializes a block into the database, header and body separately.
@ -843,7 +843,11 @@ func ReadBadBlock(db ethdb.Reader, hash common.Hash) *types.Block {
} }
for _, bad := range badBlocks { for _, bad := range badBlocks {
if bad.Header.Hash() == hash { if bad.Header.Hash() == hash {
return types.NewBlockWithHeader(bad.Header).WithBody(bad.Body.Transactions, bad.Body.Uncles).WithWithdrawals(bad.Body.Withdrawals) block := types.NewBlockWithHeader(bad.Header)
if bad.Body != nil {
block = block.WithBody(*bad.Body)
}
return block
} }
} }
return nil return nil
@ -862,7 +866,11 @@ func ReadAllBadBlocks(db ethdb.Reader) []*types.Block {
} }
var blocks []*types.Block var blocks []*types.Block
for _, bad := range badBlocks { for _, bad := range badBlocks {
blocks = append(blocks, types.NewBlockWithHeader(bad.Header).WithBody(bad.Body.Transactions, bad.Body.Uncles).WithWithdrawals(bad.Body.Withdrawals)) block := types.NewBlockWithHeader(bad.Header)
if bad.Body != nil {
block = block.WithBody(*bad.Body)
}
blocks = append(blocks, block)
} }
return blocks return blocks
} }

@ -640,7 +640,7 @@ func makeTestBlocks(nblock int, txsPerBlock int) []*types.Block {
Number: big.NewInt(int64(i)), Number: big.NewInt(int64(i)),
Extra: []byte("test block"), Extra: []byte("test block"),
} }
blocks[i] = types.NewBlockWithHeader(header).WithBody(txs, nil) blocks[i] = types.NewBlockWithHeader(header).WithBody(types.Body{Transactions: txs})
blocks[i].Hash() // pre-cache the block hash blocks[i].Hash() // pre-cache the block hash
} }
return blocks return blocks

@ -76,7 +76,7 @@ func TestLookupStorage(t *testing.T) {
tx3 := types.NewTransaction(3, common.BytesToAddress([]byte{0x33}), big.NewInt(333), 3333, big.NewInt(33333), []byte{0x33, 0x33, 0x33}) tx3 := types.NewTransaction(3, common.BytesToAddress([]byte{0x33}), big.NewInt(333), 3333, big.NewInt(33333), []byte{0x33, 0x33, 0x33})
txs := []*types.Transaction{tx1, tx2, tx3} txs := []*types.Transaction{tx1, tx2, tx3}
block := types.NewBlock(&types.Header{Number: big.NewInt(314)}, txs, nil, nil, newTestHasher()) block := types.NewBlock(&types.Header{Number: big.NewInt(314)}, &types.Body{Transactions: txs}, nil, newTestHasher())
// Check that no transactions entries are in a pristine database // Check that no transactions entries are in a pristine database
for i, tx := range txs { for i, tx := range txs {

@ -34,7 +34,7 @@ func TestChainIterator(t *testing.T) {
var block *types.Block var block *types.Block
var txs []*types.Transaction var txs []*types.Transaction
to := common.BytesToAddress([]byte{0x11}) to := common.BytesToAddress([]byte{0x11})
block = types.NewBlock(&types.Header{Number: big.NewInt(int64(0))}, nil, nil, nil, newTestHasher()) // Empty genesis block block = types.NewBlock(&types.Header{Number: big.NewInt(int64(0))}, nil, nil, newTestHasher()) // Empty genesis block
WriteBlock(chainDb, block) WriteBlock(chainDb, block)
WriteCanonicalHash(chainDb, block.Hash(), block.NumberU64()) WriteCanonicalHash(chainDb, block.Hash(), block.NumberU64())
for i := uint64(1); i <= 10; i++ { for i := uint64(1); i <= 10; i++ {
@ -60,7 +60,7 @@ func TestChainIterator(t *testing.T) {
}) })
} }
txs = append(txs, tx) txs = append(txs, tx)
block = types.NewBlock(&types.Header{Number: big.NewInt(int64(i))}, []*types.Transaction{tx}, nil, nil, newTestHasher()) block = types.NewBlock(&types.Header{Number: big.NewInt(int64(i))}, &types.Body{Transactions: types.Transactions{tx}}, nil, newTestHasher())
WriteBlock(chainDb, block) WriteBlock(chainDb, block)
WriteCanonicalHash(chainDb, block.Hash(), block.NumberU64()) WriteCanonicalHash(chainDb, block.Hash(), block.NumberU64())
} }
@ -111,7 +111,7 @@ func TestIndexTransactions(t *testing.T) {
to := common.BytesToAddress([]byte{0x11}) to := common.BytesToAddress([]byte{0x11})
// Write empty genesis block // Write empty genesis block
block = types.NewBlock(&types.Header{Number: big.NewInt(int64(0))}, nil, nil, nil, newTestHasher()) block = types.NewBlock(&types.Header{Number: big.NewInt(int64(0))}, nil, nil, newTestHasher())
WriteBlock(chainDb, block) WriteBlock(chainDb, block)
WriteCanonicalHash(chainDb, block.Hash(), block.NumberU64()) WriteCanonicalHash(chainDb, block.Hash(), block.NumberU64())
@ -138,7 +138,7 @@ func TestIndexTransactions(t *testing.T) {
}) })
} }
txs = append(txs, tx) txs = append(txs, tx)
block = types.NewBlock(&types.Header{Number: big.NewInt(int64(i))}, []*types.Transaction{tx}, nil, nil, newTestHasher()) block = types.NewBlock(&types.Header{Number: big.NewInt(int64(i))}, &types.Body{Transactions: types.Transactions{tx}}, nil, newTestHasher())
WriteBlock(chainDb, block) WriteBlock(chainDb, block)
WriteCanonicalHash(chainDb, block.Hash(), block.NumberU64()) WriteCanonicalHash(chainDb, block.Hash(), block.NumberU64())
} }

@ -417,10 +417,11 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr
header.ParentBeaconRoot = &beaconRoot header.ParentBeaconRoot = &beaconRoot
} }
// Assemble and return the final block for sealing // Assemble and return the final block for sealing
body := &types.Body{Transactions: txs}
if config.IsShanghai(header.Number, header.Time) { if config.IsShanghai(header.Number, header.Time) {
return types.NewBlockWithWithdrawals(header, txs, nil, receipts, []*types.Withdrawal{}, trie.NewStackTrie(nil)) body.Withdrawals = []*types.Withdrawal{}
} }
return types.NewBlock(header, txs, nil, receipts, trie.NewStackTrie(nil)) return types.NewBlock(header, body, receipts, trie.NewStackTrie(nil))
} }
var ( var (

@ -87,7 +87,7 @@ func (bc *testBlockChain) CurrentBlock() *types.Header {
} }
func (bc *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block { func (bc *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block {
return types.NewBlock(bc.CurrentBlock(), nil, nil, nil, trie.NewStackTrie(nil)) return types.NewBlock(bc.CurrentBlock(), nil, nil, trie.NewStackTrie(nil))
} }
func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, error) { func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, error) {

@ -23,6 +23,7 @@ import (
"io" "io"
"math/big" "math/big"
"reflect" "reflect"
"slices"
"sync/atomic" "sync/atomic"
"time" "time"
@ -217,13 +218,19 @@ type extblock struct {
// NewBlock creates a new block. The input data is copied, changes to header and to the // NewBlock creates a new block. The input data is copied, changes to header and to the
// field values will not affect the block. // field values will not affect the block.
// //
// The values of TxHash, UncleHash, ReceiptHash and Bloom in header // The body elements and the receipts are used to recompute and overwrite the
// are ignored and set to values derived from the given txs, uncles // relevant portions of the header.
// and receipts. func NewBlock(header *Header, body *Body, receipts []*Receipt, hasher TrieHasher) *Block {
func NewBlock(header *Header, txs []*Transaction, uncles []*Header, receipts []*Receipt, hasher TrieHasher) *Block { if body == nil {
b := &Block{header: CopyHeader(header)} body = &Body{}
}
var (
b = NewBlockWithHeader(header)
txs = body.Transactions
uncles = body.Uncles
withdrawals = body.Withdrawals
)
// TODO: panic if len(txs) != len(receipts)
if len(txs) == 0 { if len(txs) == 0 {
b.header.TxHash = EmptyTxsHash b.header.TxHash = EmptyTxsHash
} else { } else {
@ -249,27 +256,18 @@ func NewBlock(header *Header, txs []*Transaction, uncles []*Header, receipts []*
} }
} }
return b
}
// NewBlockWithWithdrawals creates a new block with withdrawals. 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 NewBlockWithWithdrawals(header *Header, txs []*Transaction, uncles []*Header, receipts []*Receipt, withdrawals []*Withdrawal, hasher TrieHasher) *Block {
b := NewBlock(header, txs, uncles, receipts, hasher)
if withdrawals == nil { if withdrawals == nil {
b.header.WithdrawalsHash = nil b.header.WithdrawalsHash = nil
} else if len(withdrawals) == 0 { } else if len(withdrawals) == 0 {
b.header.WithdrawalsHash = &EmptyWithdrawalsHash b.header.WithdrawalsHash = &EmptyWithdrawalsHash
b.withdrawals = Withdrawals{}
} else { } else {
h := DeriveSha(Withdrawals(withdrawals), hasher) hash := DeriveSha(Withdrawals(withdrawals), hasher)
b.header.WithdrawalsHash = &h b.header.WithdrawalsHash = &hash
b.withdrawals = slices.Clone(withdrawals)
} }
return b.WithWithdrawals(withdrawals) return b
} }
// CopyHeader creates a deep copy of a block header. // CopyHeader creates a deep copy of a block header.
@ -453,31 +451,17 @@ func (b *Block) WithSeal(header *Header) *Block {
} }
} }
// WithBody returns a copy of the block with the given transaction and uncle contents. // WithBody returns a new block with the original header and a deep copy of the
func (b *Block) WithBody(transactions []*Transaction, uncles []*Header) *Block { // provided body.
func (b *Block) WithBody(body Body) *Block {
block := &Block{ block := &Block{
header: b.header, header: b.header,
transactions: make([]*Transaction, len(transactions)), transactions: slices.Clone(body.Transactions),
uncles: make([]*Header, len(uncles)), uncles: make([]*Header, len(body.Uncles)),
withdrawals: b.withdrawals, withdrawals: slices.Clone(body.Withdrawals),
} }
copy(block.transactions, transactions) for i := range body.Uncles {
for i := range uncles { block.uncles[i] = CopyHeader(body.Uncles[i])
block.uncles[i] = CopyHeader(uncles[i])
}
return block
}
// WithWithdrawals returns a copy of the block containing the given withdrawals.
func (b *Block) WithWithdrawals(withdrawals []*Withdrawal) *Block {
block := &Block{
header: b.header,
transactions: b.transactions,
uncles: b.uncles,
}
if withdrawals != nil {
block.withdrawals = make([]*Withdrawal, len(withdrawals))
copy(block.withdrawals, withdrawals)
} }
return block return block
} }

@ -254,7 +254,7 @@ func makeBenchBlock() *Block {
Extra: []byte("benchmark uncle"), Extra: []byte("benchmark uncle"),
} }
} }
return NewBlock(header, txs, uncles, receipts, blocktest.NewHasher()) return NewBlock(header, &Body{Transactions: txs, Uncles: uncles}, receipts, blocktest.NewHasher())
} }
func TestRlpDecodeParentHash(t *testing.T) { func TestRlpDecodeParentHash(t *testing.T) {

@ -779,7 +779,7 @@ func setBlockhash(data *engine.ExecutableData) *engine.ExecutableData {
Extra: data.ExtraData, Extra: data.ExtraData,
MixDigest: data.Random, MixDigest: data.Random,
} }
block := types.NewBlockWithHeader(header).WithBody(txs, nil /* uncles */) block := types.NewBlockWithHeader(header).WithBody(types.Body{Transactions: txs})
data.BlockHash = block.Hash() data.BlockHash = block.Hash()
return data return data
} }
@ -935,7 +935,7 @@ func TestNewPayloadOnInvalidTerminalBlock(t *testing.T) {
Extra: data.ExtraData, Extra: data.ExtraData,
MixDigest: data.Random, MixDigest: data.Random,
} }
block := types.NewBlockWithHeader(header).WithBody(txs, nil /* uncles */) block := types.NewBlockWithHeader(header).WithBody(types.Body{Transactions: txs})
data.BlockHash = block.Hash() data.BlockHash = block.Hash()
// Send the new payload // Send the new payload
resp2, err := api.NewPayloadV1(data) resp2, err := api.NewPayloadV1(data)
@ -1554,7 +1554,7 @@ func TestBlockToPayloadWithBlobs(t *testing.T) {
}, },
} }
block := types.NewBlock(&header, txs, nil, nil, trie.NewStackTrie(nil)) block := types.NewBlock(&header, &types.Body{Transactions: txs}, nil, trie.NewStackTrie(nil))
envelope := engine.BlockToExecutableData(block, nil, sidecars) envelope := engine.BlockToExecutableData(block, nil, sidecars)
var want int var want int
for _, tx := range txs { for _, tx := range txs {

@ -1504,7 +1504,7 @@ func (d *Downloader) importBlockResults(results []*fetchResult) error {
) )
blocks := make([]*types.Block, len(results)) blocks := make([]*types.Block, len(results))
for i, result := range results { for i, result := range results {
blocks[i] = types.NewBlockWithHeader(result.Header).WithBody(result.Transactions, result.Uncles).WithWithdrawals(result.Withdrawals) blocks[i] = types.NewBlockWithHeader(result.Header).WithBody(result.body())
} }
// Downloaded blocks are always regarded as trusted after the // Downloaded blocks are always regarded as trusted after the
// transition. Because the downloaded chain is guided by the // transition. Because the downloaded chain is guided by the
@ -1726,7 +1726,7 @@ func (d *Downloader) commitSnapSyncData(results []*fetchResult, stateSync *state
blocks := make([]*types.Block, len(results)) blocks := make([]*types.Block, len(results))
receipts := make([]types.Receipts, len(results)) receipts := make([]types.Receipts, len(results))
for i, result := range results { for i, result := range results {
blocks[i] = types.NewBlockWithHeader(result.Header).WithBody(result.Transactions, result.Uncles).WithWithdrawals(result.Withdrawals) blocks[i] = types.NewBlockWithHeader(result.Header).WithBody(result.body())
receipts[i] = result.Receipts receipts[i] = result.Receipts
} }
if index, err := d.blockchain.InsertReceiptChain(blocks, receipts, d.ancientLimit); err != nil { if index, err := d.blockchain.InsertReceiptChain(blocks, receipts, d.ancientLimit); err != nil {
@ -1737,7 +1737,7 @@ func (d *Downloader) commitSnapSyncData(results []*fetchResult, stateSync *state
} }
func (d *Downloader) commitPivotBlock(result *fetchResult) error { func (d *Downloader) commitPivotBlock(result *fetchResult) error {
block := types.NewBlockWithHeader(result.Header).WithBody(result.Transactions, result.Uncles).WithWithdrawals(result.Withdrawals) block := types.NewBlockWithHeader(result.Header).WithBody(result.body())
log.Debug("Committing snap sync pivot as new head", "number", block.Number(), "hash", block.Hash()) log.Debug("Committing snap sync pivot as new head", "number", block.Number(), "hash", block.Hash())
// Commit the pivot block as the new head, will require full sync from here on // Commit the pivot block as the new head, will require full sync from here on

@ -87,6 +87,15 @@ func newFetchResult(header *types.Header, fastSync bool) *fetchResult {
return item return item
} }
// body returns a representation of the fetch result as a types.Body object.
func (f *fetchResult) body() types.Body {
return types.Body{
Transactions: f.Transactions,
Uncles: f.Uncles,
Withdrawals: f.Withdrawals,
}
}
// SetBodyDone flags the body as finished. // SetBodyDone flags the body as finished.
func (f *fetchResult) SetBodyDone() { func (f *fetchResult) SetBodyDone() {
if v := f.pending.Load(); (v & (1 << bodyType)) != 0 { if v := f.pending.Load(); (v & (1 << bodyType)) != 0 {

@ -191,7 +191,12 @@ func (ec *Client) getBlock(ctx context.Context, method string, args ...interface
} }
txs[i] = tx.tx txs[i] = tx.tx
} }
return types.NewBlockWithHeader(head).WithBody(txs, uncles).WithWithdrawals(body.Withdrawals), nil return types.NewBlockWithHeader(head).WithBody(
types.Body{
Transactions: txs,
Uncles: uncles,
Withdrawals: body.Withdrawals,
}), nil
} }
// HeaderByHash returns the block header with the given hash. // HeaderByHash returns the block header with the given hash.

@ -151,7 +151,7 @@ func (e *Era) GetBlockByNumber(num uint64) (*types.Block, error) {
if err := rlp.Decode(r, &body); err != nil { if err := rlp.Decode(r, &body); err != nil {
return nil, err return nil, err
} }
return types.NewBlockWithHeader(&header).WithBody(body.Transactions, body.Uncles), nil return types.NewBlockWithHeader(&header).WithBody(body), nil
} }
// Accumulator reads the accumulator entry in the Era1 file. // Accumulator reads the accumulator entry in the Era1 file.

@ -73,7 +73,7 @@ func (it *Iterator) Block() (*types.Block, error) {
if err := rlp.Decode(it.inner.Body, &body); err != nil { if err := rlp.Decode(it.inner.Body, &body); err != nil {
return nil, err return nil, err
} }
return types.NewBlockWithHeader(&header).WithBody(body.Transactions, body.Uncles), nil return types.NewBlockWithHeader(&header).WithBody(body), nil
} }
// Receipts returns the receipts for the iterator's current position. // Receipts returns the receipts for the iterator's current position.

@ -1348,7 +1348,7 @@ func TestRPCMarshalBlock(t *testing.T) {
} }
txs = append(txs, tx) txs = append(txs, tx)
} }
block := types.NewBlock(&types.Header{Number: big.NewInt(100)}, txs, nil, nil, blocktest.NewHasher()) block := types.NewBlock(&types.Header{Number: big.NewInt(100)}, &types.Body{Transactions: txs}, nil, blocktest.NewHasher())
var testSuite = []struct { var testSuite = []struct {
inclTx bool inclTx bool
@ -1559,7 +1559,7 @@ func TestRPCGetBlockOrHeader(t *testing.T) {
Address: common.Address{0x12, 0x34}, Address: common.Address{0x12, 0x34},
Amount: 10, Amount: 10,
} }
pending = types.NewBlockWithWithdrawals(&types.Header{Number: big.NewInt(11), Time: 42}, []*types.Transaction{tx}, nil, nil, []*types.Withdrawal{withdrawal}, blocktest.NewHasher()) pending = types.NewBlock(&types.Header{Number: big.NewInt(11), Time: 42}, &types.Body{Transactions: types.Transactions{tx}, Withdrawals: types.Withdrawals{withdrawal}}, nil, blocktest.NewHasher())
) )
backend := newTestBackend(t, genBlocks, genesis, ethash.NewFaker(), func(i int, b *core.BlockGen) { backend := newTestBackend(t, genBlocks, genesis, ethash.NewFaker(), func(i int, b *core.BlockGen) {
// Transfer from account[0] to account[1] // Transfer from account[0] to account[1]

@ -78,7 +78,7 @@ func (bc *testBlockChain) CurrentBlock() *types.Header {
} }
func (bc *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block { func (bc *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block {
return types.NewBlock(bc.CurrentBlock(), nil, nil, nil, trie.NewStackTrie(nil)) return types.NewBlock(bc.CurrentBlock(), nil, nil, trie.NewStackTrie(nil))
} }
func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, error) { func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, error) {