Skip to content

Commit

Permalink
Merge 19616c8 into 8454fc7
Browse files Browse the repository at this point in the history
  • Loading branch information
karlb authored Jun 7, 2023
2 parents 8454fc7 + 19616c8 commit b325dc5
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 34 deletions.
74 changes: 60 additions & 14 deletions core/types/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package types

import (
"encoding/binary"
"encoding/json"
"fmt"
"io"
Expand All @@ -35,10 +36,39 @@ import (

var (
EmptyRootHash = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
EmptyUncleHash = rlpHash([]*Header(nil)) // 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347
EmptyRandomness = Randomness{}
EmptyEpochSnarkData = EpochSnarkData{}
EmptyMixDigest = common.HexToHash("0000000000000000000000000000000000000000000000000000000000000000")
)

// A BlockNonce is a 64-bit hash which proves (combined with the
// mix-hash) that a sufficient amount of computation has been carried
// out on a block.
type BlockNonce [8]byte

// EncodeNonce converts the given integer to a block nonce.
func EncodeNonce(i uint64) BlockNonce {
var n BlockNonce
binary.BigEndian.PutUint64(n[:], i)
return n
}

// Uint64 returns the integer value of a block nonce.
func (n BlockNonce) Uint64() uint64 {
return binary.BigEndian.Uint64(n[:])
}

// MarshalText encodes n as a hex string with 0x prefix.
func (n BlockNonce) MarshalText() ([]byte, error) {
return hexutil.Bytes(n[:]).MarshalText()
}

// UnmarshalText implements encoding.TextUnmarshaler.
func (n *BlockNonce) UnmarshalText(input []byte) error {
return hexutil.UnmarshalFixedText("BlockNonce", input, n[:])
}

//go:generate gencodec -type Header -field-override headerMarshaling -out gen_header_json.go

// Header represents a block header in the Ethereum blockchain.
Expand All @@ -60,16 +90,22 @@ type Header struct {
extraError error

GasLimit uint64 `json:"gasLimit" rlp:"optional"`
// Proof-of-work fields for Eth compatibility
Difficulty *big.Int `json:"difficulty" rlp:"optional"`
Nonce BlockNonce `json:"nonce" rlp:"optional"`
UncleHash common.Hash `json:"sha3Uncles" rlp:"optional"`
MixDigest common.Hash `json:"mixHash" rlp:"optional"`
}

// field type overrides for gencodec
type headerMarshaling struct {
Number *hexutil.Big
GasLimit hexutil.Uint64
GasUsed hexutil.Uint64
Time hexutil.Uint64
Extra hexutil.Bytes
Hash common.Hash `json:"hash"` // adds call to Hash() in MarshalJSON
Number *hexutil.Big
GasLimit hexutil.Uint64
GasUsed hexutil.Uint64
Time hexutil.Uint64
Extra hexutil.Bytes
Hash common.Hash `json:"hash"` // adds call to Hash() in MarshalJSON
Difficulty *hexutil.Big
}

// Hash returns the block hash of the header, which is simply the keccak256 hash of its
Expand Down Expand Up @@ -286,15 +322,19 @@ func NewBlockWithHeader(header *Header) *Block {
func CopyHeader(h *Header) *Header {
cpy := Header{
ParentHash: h.ParentHash,
UncleHash: h.UncleHash,
Coinbase: h.Coinbase,
Root: h.Root,
TxHash: h.TxHash,
ReceiptHash: h.ReceiptHash,
Bloom: h.Bloom,
Difficulty: h.Difficulty,
Number: new(big.Int),
GasLimit: h.GasLimit,
GasUsed: h.GasUsed,
Time: h.Time,
MixDigest: h.MixDigest,
Nonce: h.Nonce,
}

if h.Number != nil {
Expand Down Expand Up @@ -345,17 +385,23 @@ func (b *Block) Transaction(hash common.Hash) *Transaction {
}

func (b *Block) Number() *big.Int { return new(big.Int).Set(b.header.Number) }
func (b *Block) GasLimit() uint64 { return b.header.GasLimit }
func (b *Block) GasUsed() uint64 { return b.header.GasUsed }
func (b *Block) Difficulty() *big.Int { return new(big.Int).Set(b.header.Difficulty) }
func (b *Block) Time() uint64 { return b.header.Time }
func (b *Block) TotalDifficulty() *big.Int { return new(big.Int).Add(b.header.Number, big.NewInt(1)) }
func (b *Block) NumberU64() uint64 { return b.header.Number.Uint64() }
func (b *Block) Bloom() Bloom { return b.header.Bloom }
func (b *Block) Coinbase() common.Address { return b.header.Coinbase }
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) Extra() []byte { return common.CopyBytes(b.header.Extra) }

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) 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) }

func (b *Block) Header() *Header { return CopyHeader(b.header) }
func (b *Block) MutableHeader() *Header { return b.header }
Expand Down
24 changes: 24 additions & 0 deletions core/types/gen_header_json.go

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

31 changes: 18 additions & 13 deletions e2e_test/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,7 @@ func TestEthersJSCompatibility(t *testing.T) {
err = network[0].Tracker.AwaitBlock(ctx, num+1)
require.NoError(t, err)
block := network[0].Tracker.GetProcessedBlock(num)
require.NotNil(t, block)

// Prune state
err = pruneStateOfBlock(ctx, network[0], block.Hash())
Expand Down Expand Up @@ -601,10 +602,10 @@ func TestEthersJSCompatibilityDisable(t *testing.T) {
err = network[0].WsClient.GetRPCClient().CallContext(ctx, &result, "eth_getBlockByNumber", "latest", true)
require.NoError(t, err)

_, ok := result["gasLimit"]
assert.True(t, ok, "gasLimit field should be present on RPC block")
_, ok = result["baseFeePerGas"]
assert.True(t, ok, "baseFeePerGas field should be present on RPC block")
for _, field := range []string{"gasLimit", "baseFeePerGas", "sha3Uncles", "uncles", "nonce", "mixHash", "difficulty"} {
_, ok := result[field]
assert.Truef(t, ok, "%s field should be present on RPC block after GFork", field)
}

// Turn off compatibility and check fields are not present
ec.RPCEthCompatibility = false
Expand All @@ -621,7 +622,7 @@ func TestEthersJSCompatibilityDisable(t *testing.T) {

// After GFork, gasLimit should be returned directly from the header, even if
// RPCEthCompatibility is off, since it is now part of the header hash.
_, ok = result["gasLimit"]
_, ok := result["gasLimit"]
assert.True(t, ok, "gasLimit field must be present on RPC block after GFork")
_, ok = result["baseFeePerGas"]
assert.False(t, ok, "baseFeePerGas field must be present on RPC block")
Expand All @@ -648,10 +649,14 @@ func TestEthersJSCompatibilityDisableBeforeGFork(t *testing.T) {
err = network[0].WsClient.GetRPCClient().CallContext(ctx, &result, "eth_getBlockByNumber", "latest", true)
require.NoError(t, err)

_, ok := result["gasLimit"]
assert.True(t, ok, "gasLimit field should be present on RPC block")
_, ok = result["baseFeePerGas"]
assert.True(t, ok, "baseFeePerGas field should be present on RPC block")
for _, field := range []string{"gasLimit", "baseFeePerGas", "difficulty"} {
_, ok := result[field]
assert.Truef(t, ok, "%s field should be present on RPC block before GFork", field)
}
for _, field := range []string{"sha3Uncles", "uncles", "nonce", "mixHash"} {
_, ok := result[field]
assert.Falsef(t, ok, "%s field should not be present on RPC block before GFork", field)
}

// Turn off compatibility and check fields are not present
ec.RPCEthCompatibility = false
Expand All @@ -666,8 +671,8 @@ func TestEthersJSCompatibilityDisableBeforeGFork(t *testing.T) {
err = network[0].WsClient.GetRPCClient().CallContext(ctx, &result, "eth_getBlockByNumber", "latest", true)
require.NoError(t, err)

_, ok = result["gasLimit"]
assert.False(t, ok, "gasLimit field should not be present on RPC block before GFork")
_, ok = result["baseFeePerGas"]
assert.False(t, ok, "baseFeePerGas field should not be present on RPC block")
for _, field := range []string{"gasLimit", "baseFeePerGas", "sha3Uncles", "uncles", "nonce", "mixHash", "difficulty"} {
_, ok := result[field]
assert.Falsef(t, ok, "%s field should not be present on RPC block before GFork", field)
}
}
15 changes: 9 additions & 6 deletions ethclient/ethclient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -308,8 +308,11 @@ func testHeader(t *testing.T, chain []*types.Block, client *rpc.Client) {
if got != nil && got.Number != nil && got.Number.Sign() == 0 {
got.Number = big.NewInt(0) // hack to make DeepEqual work
}
if got != nil && got.Difficulty != nil && got.Difficulty.Sign() == 0 {
got.Difficulty = big.NewInt(0) // hack to make DeepEqual work
}
if !reflect.DeepEqual(got, tt.want) {
t.Fatalf("HeaderByNumber(%v)\n = %v\nwant %v", tt.block, got, tt.want)
t.Fatalf("HeaderByNumber(%v)\n = %+v\nwant %+v", tt.block, got, tt.want)
}
})
}
Expand Down Expand Up @@ -396,39 +399,39 @@ func testGetBlock(t *testing.T, client *rpc.Client) {
// Get current block number
blockNumber, err := ec.BlockNumber(context.Background())
if err != nil {
t.Fatalf("unexpected error: %v", err)
t.Fatalf("BlockNumber: %v", err)
}
if blockNumber != 1 {
t.Fatalf("BlockNumber returned wrong number: %d", blockNumber)
}
// Get current block by number
block, err := ec.BlockByNumber(context.Background(), new(big.Int).SetUint64(blockNumber))
if err != nil {
t.Fatalf("unexpected error: %v", err)
t.Fatalf("BlockByNumber: %v", err)
}
if block.NumberU64() != blockNumber {
t.Fatalf("BlockByNumber returned wrong block: want %d got %d", blockNumber, block.NumberU64())
}
// Get current block by hash
blockH, err := ec.BlockByHash(context.Background(), block.Hash())
if err != nil {
t.Fatalf("unexpected error: %v", err)
t.Fatalf("BlockByHash: %v", err)
}
if block.Hash() != blockH.Hash() {
t.Fatalf("BlockByHash returned wrong block: want %v got %v", block.Hash().Hex(), blockH.Hash().Hex())
}
// Get header by number
header, err := ec.HeaderByNumber(context.Background(), new(big.Int).SetUint64(blockNumber))
if err != nil {
t.Fatalf("unexpected error: %v", err)
t.Fatalf("HeaderByNumber: %v", err)
}
if block.Header().Hash() != header.Hash() {
t.Fatalf("HeaderByNumber returned wrong header: want %v got %v", block.Header().Hash().Hex(), header.Hash().Hex())
}
// Get header by hash
headerH, err := ec.HeaderByHash(context.Background(), block.Hash())
if err != nil {
t.Fatalf("unexpected error: %v", err)
t.Fatalf("HeaderByHash: %v", err)
}
if block.Header().Hash() != headerH.Hash() {
t.Fatalf("HeaderByHash returned wrong header: want %v got %v", block.Header().Hash().Hex(), headerH.Hash().Hex())
Expand Down
9 changes: 9 additions & 0 deletions internal/ethapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -1149,6 +1149,15 @@ func RPCMarshalHeader(head *types.Header) map[string]interface{} {
"transactionsRoot": head.TxHash,
"receiptsRoot": head.ReceiptHash,
}
// Former proof-of-work fields, now constants, see https://eips.ethereum.org/EIPS/eip-3675#block-structure
// Set after GFork
if head.Difficulty != nil {
result["difficulty"] = (*hexutil.Big)(head.Difficulty)
result["nonce"] = head.Nonce
result["sha3Uncles"] = head.UncleHash
result["uncles"] = []interface{}{}
result["mixHash"] = head.MixDigest
}

return result
}
Expand Down
4 changes: 4 additions & 0 deletions miner/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ func prepareBlock(w *worker) (*blockState, error) {
b.gasPool = new(core.GasPool).AddGas(b.gasLimit)
if w.chainConfig.IsGFork(header.Number) {
header.GasLimit = b.gasLimit
header.Difficulty = big.NewInt(0)
header.Nonce = types.EncodeNonce(0)
header.UncleHash = types.EmptyUncleHash
header.MixDigest = types.EmptyMixDigest
}

// Play our part in generating the random beacon.
Expand Down
2 changes: 1 addition & 1 deletion monorepo_commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
d216e7599f499adec2e0200e599f601ea5424cde
a70a729f9785ad0130d8605493b008210cb22326

0 comments on commit b325dc5

Please sign in to comment.