diff --git a/beacon/engine/gen_ed.go b/beacon/engine/gen_ed.go index 2a92e7420407..0ae5a3b8f1f1 100644 --- a/beacon/engine/gen_ed.go +++ b/beacon/engine/gen_ed.go @@ -34,7 +34,7 @@ func (e ExecutableData) MarshalJSON() ([]byte, error) { Withdrawals []*types.Withdrawal `json:"withdrawals"` BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"` ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"` - ExecutionWitness *types.ExecutionWitness `json:"executionWitness"` + ExecutionWitness *types.ExecutionWitness `json:"executionWitness,omitempty"` } var enc ExecutableData enc.ParentHash = e.ParentHash @@ -83,7 +83,7 @@ func (e *ExecutableData) UnmarshalJSON(input []byte) error { Withdrawals []*types.Withdrawal `json:"withdrawals"` BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"` ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"` - ExecutionWitness *types.ExecutionWitness `json:"executionWitness"` + ExecutionWitness *types.ExecutionWitness `json:"executionWitness,omitempty"` } var dec ExecutableData if err := json.Unmarshal(input, &dec); err != nil { diff --git a/beacon/engine/types.go b/beacon/engine/types.go index 0066e9181756..5a6fa7827388 100644 --- a/beacon/engine/types.go +++ b/beacon/engine/types.go @@ -47,25 +47,24 @@ type payloadAttributesMarshaling struct { // ExecutableData is the data necessary to execute an EL payload. type ExecutableData struct { - ParentHash common.Hash `json:"parentHash" gencodec:"required"` - FeeRecipient common.Address `json:"feeRecipient" gencodec:"required"` - StateRoot common.Hash `json:"stateRoot" gencodec:"required"` - ReceiptsRoot common.Hash `json:"receiptsRoot" gencodec:"required"` - LogsBloom []byte `json:"logsBloom" gencodec:"required"` - Random common.Hash `json:"prevRandao" gencodec:"required"` - Number uint64 `json:"blockNumber" gencodec:"required"` - GasLimit uint64 `json:"gasLimit" gencodec:"required"` - GasUsed uint64 `json:"gasUsed" gencodec:"required"` - Timestamp uint64 `json:"timestamp" gencodec:"required"` - ExtraData []byte `json:"extraData" gencodec:"required"` - BaseFeePerGas *big.Int `json:"baseFeePerGas" gencodec:"required"` - BlockHash common.Hash `json:"blockHash" gencodec:"required"` - Transactions [][]byte `json:"transactions" gencodec:"required"` - Withdrawals []*types.Withdrawal `json:"withdrawals"` - BlobGasUsed *uint64 `json:"blobGasUsed"` - ExcessBlobGas *uint64 `json:"excessBlobGas"` - - ExecutionWitness *types.ExecutionWitness `json:"executionWitness"` + ParentHash common.Hash `json:"parentHash" gencodec:"required"` + FeeRecipient common.Address `json:"feeRecipient" gencodec:"required"` + StateRoot common.Hash `json:"stateRoot" gencodec:"required"` + ReceiptsRoot common.Hash `json:"receiptsRoot" gencodec:"required"` + LogsBloom []byte `json:"logsBloom" gencodec:"required"` + Random common.Hash `json:"prevRandao" gencodec:"required"` + Number uint64 `json:"blockNumber" gencodec:"required"` + GasLimit uint64 `json:"gasLimit" gencodec:"required"` + GasUsed uint64 `json:"gasUsed" gencodec:"required"` + Timestamp uint64 `json:"timestamp" gencodec:"required"` + ExtraData []byte `json:"extraData" gencodec:"required"` + BaseFeePerGas *big.Int `json:"baseFeePerGas" gencodec:"required"` + BlockHash common.Hash `json:"blockHash" gencodec:"required"` + Transactions [][]byte `json:"transactions" gencodec:"required"` + Withdrawals []*types.Withdrawal `json:"withdrawals"` + BlobGasUsed *uint64 `json:"blobGasUsed"` + ExcessBlobGas *uint64 `json:"excessBlobGas"` + ExecutionWitness *types.ExecutionWitness `json:"executionWitness,omitempty"` } // JSON type overrides for executableData. diff --git a/consensus/beacon/consensus.go b/consensus/beacon/consensus.go index e40c180aa421..c602a7364071 100644 --- a/consensus/beacon/consensus.go +++ b/consensus/beacon/consensus.go @@ -398,9 +398,10 @@ func (beacon *Beacon) FinalizeAndAssemble(chain consensus.ChainHeaderReader, hea state.Database().SaveTransitionState(header.Root) var ( - p *verkle.VerkleProof - k verkle.StateDiff - keys = state.Witness().Keys() + p *verkle.VerkleProof + k verkle.StateDiff + keys = state.Witness().Keys() + proot common.Hash ) if chain.Config().IsPrague(header.Number, header.Time) { // Open the pre-tree to prove the pre-state against @@ -408,6 +409,7 @@ func (beacon *Beacon) FinalizeAndAssemble(chain consensus.ChainHeaderReader, hea if parent == nil { return nil, fmt.Errorf("nil parent header for block %d", header.Number) } + proot = parent.Root // Load transition state at beginning of block, because // OpenTrie needs to know what the conversion status is. @@ -467,7 +469,7 @@ func (beacon *Beacon) FinalizeAndAssemble(chain consensus.ChainHeaderReader, hea // Assemble and return the final block. block := types.NewBlockWithWithdrawals(header, txs, uncles, receipts, withdrawals, trie.NewStackTrie(nil)) if chain.Config().IsPrague(header.Number, header.Time) && chain.Config().ProofInBlocks { - block.SetVerkleProof(p, k) + block.SetVerkleProof(p, k, proot) } return block, nil } diff --git a/core/chain_makers.go b/core/chain_makers.go index 1c232e6b6d92..7111d3644917 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -358,19 +358,20 @@ func GenerateChainWithGenesis(genesis *Genesis, engine consensus.Engine, n int, panic(err) } if genesis.Config != nil && genesis.Config.IsPrague(genesis.ToBlock().Number(), genesis.ToBlock().Time()) { - blocks, receipts, _, _ := GenerateVerkleChain(genesis.Config, genesis.ToBlock(), engine, db, n, gen) + blocks, receipts, _, _, _ := GenerateVerkleChain(genesis.Config, genesis.ToBlock(), engine, db, n, gen) return db, blocks, receipts } blocks, receipts := GenerateChain(genesis.Config, genesis.ToBlock(), engine, db, n, gen) return db, blocks, receipts } -func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine consensus.Engine, diskdb ethdb.Database, n int, gen func(int, *BlockGen)) ([]*types.Block, []types.Receipts, []*verkle.VerkleProof, []verkle.StateDiff) { +func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine consensus.Engine, diskdb ethdb.Database, n int, gen func(int, *BlockGen)) ([]*types.Block, []types.Receipts, []*verkle.VerkleProof, []verkle.StateDiff, []common.Hash) { if config == nil { config = params.TestChainConfig } proofs := make([]*verkle.VerkleProof, 0, n) keyvals := make([]verkle.StateDiff, 0, n) + proots := make([]common.Hash, 0, n) blocks, receipts := make(types.Blocks, n), make([]types.Receipts, n) chainreader := &generatedLinearChainReader{ config: config, @@ -428,6 +429,7 @@ func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine proofs = append(proofs, block.ExecutionWitness().VerkleProof) keyvals = append(keyvals, block.ExecutionWitness().StateDiff) + proots = append(proots, parent.Root()) return block, b.receipts } @@ -450,7 +452,7 @@ func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine parent = block snaps = statedb.Snaps() } - return blocks, receipts, proofs, keyvals + return blocks, receipts, proofs, keyvals, proots } func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.StateDB, engine consensus.Engine) *types.Header { diff --git a/core/state_processor_test.go b/core/state_processor_test.go index 991f4e2de68e..b3d513388586 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -505,7 +505,7 @@ func TestProcessVerkle(t *testing.T) { txCost1*2 + txCost2 + contractCreationCost + codeWithExtCodeCopyGas, } // TODO utiliser GenerateChainWithGenesis pour le rendre plus pratique - chain, _, proofs, keyvals := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 2, func(i int, gen *BlockGen) { + chain, _, proofs, keyvals, _ := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 2, func(i int, gen *BlockGen) { gen.SetPoS() // TODO need to check that the tx cost provided is the exact amount used (no remaining left-over) @@ -642,7 +642,7 @@ func TestProcessVerkleInvalidContractCreation(t *testing.T) { // Create two blocks that reproduce what is happening on kaustinen. // - The first block contains two failing contract creation transactions, that write to storage before they revert. // - The second block contains a single failing contract creation transaction, that fails right off the bat. - _, _, _, statediff := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 2, func(i int, gen *BlockGen) { + _, _, _, statediff, _ := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 2, func(i int, gen *BlockGen) { gen.SetPoS() if i == 0 { @@ -797,7 +797,7 @@ func TestProcessVerkleContractWithEmptyCode(t *testing.T) { // is now independent of the blockchain database. gspec.MustCommit(gendb) - _, _, _, statediff := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 1, func(i int, gen *BlockGen) { + _, _, _, statediff, _ := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 1, func(i int, gen *BlockGen) { gen.SetPoS() var tx types.Transaction // a transaction that does some PUSH1n but returns a 0-sized contract @@ -922,7 +922,7 @@ func TestProcessVerklExtCodeHashOpcode(t *testing.T) { 0x3F, // EXTCODEHASH } extCodeHashContractAddr := common.HexToAddress("db7d6ab1f17c6b31909ae466702703daef9269cf") - _, _, _, statediff := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 2, func(i int, gen *BlockGen) { + _, _, _, statediff, _ := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 2, func(i int, gen *BlockGen) { gen.SetPoS() if i == 0 { @@ -1023,7 +1023,7 @@ func TestProcessVerkleBalanceOpcode(t *testing.T) { // is now independent of the blockchain database. gspec.MustCommit(gendb) - _, _, _, statediff := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 1, func(i int, gen *BlockGen) { + _, _, _, statediff, _ := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 1, func(i int, gen *BlockGen) { gen.SetPoS() txData := []byte{ 0x73, // PUSH20 @@ -1132,7 +1132,7 @@ func TestProcessVerkleSelfDestructInSeparateTx(t *testing.T) { 0xFF, // SELFDESTRUCT } selfDestructContractAddr := common.HexToAddress("3a220f351252089d385b29beca14e27f204c296a") - _, _, _, statediff := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 2, func(i int, gen *BlockGen) { + _, _, _, statediff, _ := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 2, func(i int, gen *BlockGen) { gen.SetPoS() if i == 0 { @@ -1269,7 +1269,7 @@ func TestProcessVerkleSelfDestructInSameTx(t *testing.T) { 0xFF, // SELFDESTRUCT } selfDestructContractAddr := common.HexToAddress("3a220f351252089d385b29beca14e27f204c296a") - _, _, _, statediff := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 1, func(i int, gen *BlockGen) { + _, _, _, statediff, _ := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 1, func(i int, gen *BlockGen) { gen.SetPoS() tx, _ := types.SignTx(types.NewContractCreation(0, big.NewInt(42), 100_000, big.NewInt(875000000), selfDestructContract), signer, testKey) gen.AddTx(tx) @@ -1403,7 +1403,7 @@ func TestProcessVerkleSelfDestructInSeparateTxWithSelfBeneficiary(t *testing.T) 0xFF, // SELFDESTRUCT } selfDestructContractAddr := common.HexToAddress("3a220f351252089d385b29beca14e27f204c296a") - _, _, _, statediff := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 2, func(i int, gen *BlockGen) { + _, _, _, statediff, _ := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 2, func(i int, gen *BlockGen) { gen.SetPoS() if i == 0 { // Create selfdestruct contract, sending 42 wei. @@ -1514,7 +1514,7 @@ func TestProcessVerkleSelfDestructInSameTxWithSelfBeneficiary(t *testing.T) { 0xFF, // SELFDESTRUCT } selfDestructContractAddr := common.HexToAddress("3a220f351252089d385b29beca14e27f204c296a") - _, _, _, statediff := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 1, func(i int, gen *BlockGen) { + _, _, _, statediff, _ := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 1, func(i int, gen *BlockGen) { gen.SetPoS() tx, _ := types.SignTx(types.NewContractCreation(0, big.NewInt(42), 100_000, big.NewInt(875000000), selfDestructContract), signer, testKey) gen.AddTx(tx) diff --git a/core/types/block.go b/core/types/block.go index 64c9fe80ff22..842c9cbb7171 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -60,14 +60,16 @@ func (n *BlockNonce) UnmarshalText(input []byte) error { } type ExecutionWitness struct { - StateDiff verkle.StateDiff `json:"stateDiff"` - VerkleProof *verkle.VerkleProof `json:"verkleProof"` + StateDiff verkle.StateDiff `json:"stateDiff"` + VerkleProof *verkle.VerkleProof `json:"verkleProof"` + ParentStateRoot common.Hash `json:"parentStateRoot"` } func (ew *ExecutionWitness) Copy() *ExecutionWitness { return &ExecutionWitness{ - StateDiff: ew.StateDiff.Copy(), - VerkleProof: ew.VerkleProof.Copy(), + StateDiff: ew.StateDiff.Copy(), + VerkleProof: ew.VerkleProof.Copy(), + ParentStateRoot: ew.ParentStateRoot, } } @@ -421,8 +423,8 @@ func (b *Block) SanityCheck() error { return b.header.SanityCheck() } -func (b *Block) SetVerkleProof(vp *verkle.VerkleProof, statediff verkle.StateDiff) { - b.header.ExecutionWitness = &ExecutionWitness{statediff, vp} +func (b *Block) SetVerkleProof(vp *verkle.VerkleProof, statediff verkle.StateDiff, parentRoot common.Hash) { + b.header.ExecutionWitness = &ExecutionWitness{statediff, vp, parentRoot} if statediff == nil { b.header.ExecutionWitness.StateDiff = []verkle.StemStateDiff{} } diff --git a/core/types/gen_header_json.go b/core/types/gen_header_json.go index bac475959dd9..806aeea9ec55 100644 --- a/core/types/gen_header_json.go +++ b/core/types/gen_header_json.go @@ -16,26 +16,27 @@ var _ = (*headerMarshaling)(nil) // MarshalJSON marshals as JSON. func (h Header) MarshalJSON() ([]byte, error) { type Header struct { - ParentHash common.Hash `json:"parentHash" gencodec:"required"` - UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"` - Coinbase common.Address `json:"miner"` - Root common.Hash `json:"stateRoot" gencodec:"required"` - TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` - ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"` - Bloom Bloom `json:"logsBloom" gencodec:"required"` - Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` - Number *hexutil.Big `json:"number" gencodec:"required"` - GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"` - GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"` - Time hexutil.Uint64 `json:"timestamp" gencodec:"required"` - Extra hexutil.Bytes `json:"extraData" gencodec:"required"` - MixDigest common.Hash `json:"mixHash"` - Nonce BlockNonce `json:"nonce"` - BaseFee *hexutil.Big `json:"baseFeePerGas" rlp:"optional"` - WithdrawalsHash *common.Hash `json:"withdrawalsRoot" rlp:"optional"` - BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed" rlp:"optional"` - ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas" rlp:"optional"` - Hash common.Hash `json:"hash"` + ParentHash common.Hash `json:"parentHash" gencodec:"required"` + UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"` + Coinbase common.Address `json:"miner"` + Root common.Hash `json:"stateRoot" gencodec:"required"` + TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` + ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"` + Bloom Bloom `json:"logsBloom" gencodec:"required"` + Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` + Number *hexutil.Big `json:"number" gencodec:"required"` + GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"` + GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"` + Time hexutil.Uint64 `json:"timestamp" gencodec:"required"` + Extra hexutil.Bytes `json:"extraData" gencodec:"required"` + MixDigest common.Hash `json:"mixHash"` + Nonce BlockNonce `json:"nonce"` + BaseFee *hexutil.Big `json:"baseFeePerGas" rlp:"optional"` + WithdrawalsHash *common.Hash `json:"withdrawalsRoot" rlp:"optional"` + BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed" rlp:"optional"` + ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas" rlp:"optional"` + ExecutionWitness *ExecutionWitness `json:"executionWitness" rlp:"-"` + Hash common.Hash `json:"hash"` } var enc Header enc.ParentHash = h.ParentHash @@ -57,6 +58,7 @@ func (h Header) MarshalJSON() ([]byte, error) { enc.WithdrawalsHash = h.WithdrawalsHash enc.BlobGasUsed = (*hexutil.Uint64)(h.BlobGasUsed) enc.ExcessBlobGas = (*hexutil.Uint64)(h.ExcessBlobGas) + enc.ExecutionWitness = h.ExecutionWitness enc.Hash = h.Hash() return json.Marshal(&enc) } @@ -64,25 +66,26 @@ func (h Header) MarshalJSON() ([]byte, error) { // UnmarshalJSON unmarshals from JSON. func (h *Header) UnmarshalJSON(input []byte) error { type Header struct { - ParentHash *common.Hash `json:"parentHash" gencodec:"required"` - UncleHash *common.Hash `json:"sha3Uncles" gencodec:"required"` - Coinbase *common.Address `json:"miner"` - Root *common.Hash `json:"stateRoot" gencodec:"required"` - TxHash *common.Hash `json:"transactionsRoot" gencodec:"required"` - ReceiptHash *common.Hash `json:"receiptsRoot" gencodec:"required"` - Bloom *Bloom `json:"logsBloom" gencodec:"required"` - Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` - Number *hexutil.Big `json:"number" gencodec:"required"` - GasLimit *hexutil.Uint64 `json:"gasLimit" gencodec:"required"` - GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"` - Time *hexutil.Uint64 `json:"timestamp" gencodec:"required"` - Extra *hexutil.Bytes `json:"extraData" gencodec:"required"` - MixDigest *common.Hash `json:"mixHash"` - Nonce *BlockNonce `json:"nonce"` - BaseFee *hexutil.Big `json:"baseFeePerGas" rlp:"optional"` - WithdrawalsHash *common.Hash `json:"withdrawalsRoot" rlp:"optional"` - BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed" rlp:"optional"` - ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas" rlp:"optional"` + ParentHash *common.Hash `json:"parentHash" gencodec:"required"` + UncleHash *common.Hash `json:"sha3Uncles" gencodec:"required"` + Coinbase *common.Address `json:"miner"` + Root *common.Hash `json:"stateRoot" gencodec:"required"` + TxHash *common.Hash `json:"transactionsRoot" gencodec:"required"` + ReceiptHash *common.Hash `json:"receiptsRoot" gencodec:"required"` + Bloom *Bloom `json:"logsBloom" gencodec:"required"` + Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` + Number *hexutil.Big `json:"number" gencodec:"required"` + GasLimit *hexutil.Uint64 `json:"gasLimit" gencodec:"required"` + GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"` + Time *hexutil.Uint64 `json:"timestamp" gencodec:"required"` + Extra *hexutil.Bytes `json:"extraData" gencodec:"required"` + MixDigest *common.Hash `json:"mixHash"` + Nonce *BlockNonce `json:"nonce"` + BaseFee *hexutil.Big `json:"baseFeePerGas" rlp:"optional"` + WithdrawalsHash *common.Hash `json:"withdrawalsRoot" rlp:"optional"` + BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed" rlp:"optional"` + ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas" rlp:"optional"` + ExecutionWitness *ExecutionWitness `json:"executionWitness" rlp:"-"` } var dec Header if err := json.Unmarshal(input, &dec); err != nil { @@ -157,5 +160,8 @@ func (h *Header) UnmarshalJSON(input []byte) error { if dec.ExcessBlobGas != nil { h.ExcessBlobGas = (*uint64)(dec.ExcessBlobGas) } + if dec.ExecutionWitness != nil { + h.ExecutionWitness = dec.ExecutionWitness + } return nil } diff --git a/miner/worker_test.go b/miner/worker_test.go index d8a5f8437228..3395716da531 100644 --- a/miner/worker_test.go +++ b/miner/worker_test.go @@ -158,7 +158,7 @@ func (b *testWorkerBackend) newRandomVerkleUncle() *types.Block { } else { parent = b.chain.GetBlockByHash(b.chain.CurrentBlock().ParentHash) } - blocks, _, _, _ := core.GenerateVerkleChain(b.chain.Config(), parent, b.chain.Engine(), b.db, 1, func(i int, gen *core.BlockGen) { + blocks, _, _, _, _ := core.GenerateVerkleChain(b.chain.Config(), parent, b.chain.Engine(), b.db, 1, func(i int, gen *core.BlockGen) { var addr = make([]byte, common.AddressLength) rand.Read(addr) gen.SetCoinbase(common.BytesToAddress(addr))