Skip to content

Commit 282b9be

Browse files
Kourin1996piersy
andcommitted
Add totalDifficulty field to JSON-RPC schema of Celo1 block (#310)
* Add totalDifficulty field to JSON-RPC response for Celo1 header & block * Fix test * Remove new line --------- Co-authored-by: piersy <[email protected]>
1 parent f8e8037 commit 282b9be

File tree

2 files changed

+95
-4
lines changed

2 files changed

+95
-4
lines changed

internal/ethapi/api.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ func (api *BlockChainAPI) GetHeaderByNumber(ctx context.Context, number rpc.Bloc
502502
header, err := api.b.HeaderByNumber(ctx, number)
503503
if header != nil && err == nil {
504504
header := PopulatePreGingerbreadHeaderFields(ctx, api.b, header)
505-
response := RPCMarshalHeader(header)
505+
response := RPCMarshalHeader(header, isCelo1Block(api.b.ChainConfig(), header.Time))
506506
if number == rpc.PendingBlockNumber && api.b.ChainConfig().Optimism == nil {
507507
// Pending header need to nil out a few fields
508508
for _, field := range []string{"hash", "nonce", "miner"} {
@@ -519,7 +519,7 @@ func (api *BlockChainAPI) GetHeaderByHash(ctx context.Context, hash common.Hash)
519519
header, _ := api.b.HeaderByHash(ctx, hash)
520520
if header != nil {
521521
header := PopulatePreGingerbreadHeaderFields(ctx, api.b, header)
522-
return RPCMarshalHeader(header)
522+
return RPCMarshalHeader(header, isCelo1Block(api.b.ChainConfig(), header.Time))
523523
}
524524
return nil
525525
}
@@ -1016,7 +1016,7 @@ func (api *BlockChainAPI) EstimateGas(ctx context.Context, args TransactionArgs,
10161016
}
10171017

10181018
// RPCMarshalHeader converts the given header to the RPC output .
1019-
func RPCMarshalHeader(head *types.Header) map[string]interface{} {
1019+
func RPCMarshalHeader(head *types.Header, isCelo1 bool) map[string]interface{} {
10201020
result := map[string]interface{}{
10211021
"number": (*hexutil.Big)(head.Number),
10221022
"hash": head.Hash(),
@@ -1053,14 +1053,23 @@ func RPCMarshalHeader(head *types.Header) map[string]interface{} {
10531053
if head.RequestsHash != nil {
10541054
result["requestsHash"] = head.RequestsHash
10551055
}
1056+
if isCelo1 {
1057+
result["totalDifficulty"] = (*hexutil.Big)(new(big.Int).Add(head.Number, common.Big1))
1058+
}
10561059
return result
10571060
}
10581061

1062+
// isCelo1Block determines whether the given block is a Celo1 block
1063+
// based on the chain config and the provided block time
1064+
func isCelo1Block(config *params.ChainConfig, blockTime uint64) bool {
1065+
return config.Cel2Time != nil && !config.IsCel2(blockTime)
1066+
}
1067+
10591068
// RPCMarshalBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are
10601069
// returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain
10611070
// transaction hashes.
10621071
func RPCMarshalBlock(ctx context.Context, block *types.Block, inclTx bool, fullTx bool, config *params.ChainConfig, backend Backend) (map[string]interface{}, error) {
1063-
fields := RPCMarshalHeader(block.Header())
1072+
fields := RPCMarshalHeader(block.Header(), isCelo1Block(config, block.Header().Time))
10641073
fields["size"] = hexutil.Uint64(block.Size())
10651074

10661075
if inclTx {

internal/ethapi/celo_api_test.go

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
package ethapi
22

33
import (
4+
"context"
45
"math/big"
56
"testing"
67

78
"github.com/ethereum/go-ethereum/common"
89
"github.com/ethereum/go-ethereum/common/hexutil"
910
"github.com/ethereum/go-ethereum/core/types"
1011
"github.com/ethereum/go-ethereum/crypto"
12+
"github.com/ethereum/go-ethereum/internal/blocktest"
1113
"github.com/ethereum/go-ethereum/params"
1214
"github.com/stretchr/testify/assert"
1315
"github.com/stretchr/testify/require"
@@ -506,3 +508,83 @@ func checkTxFields(
506508
assert.Equal(t, (*hexutil.Big)(tx.GatewayFee()), rpcTx.GatewayFee)
507509
assert.Equal(t, tx.GatewayFeeRecipient(), rpcTx.GatewayFeeRecipient)
508510
}
511+
512+
// Test_isCelo1Block tests isCelo1Block function to determine whether the given block time
513+
// corresponds to Celo1 chain based on the provided chain configuration
514+
func Test_isCelo1Block(t *testing.T) {
515+
cel2Time := uint64(1000)
516+
517+
t.Run("Non-Celo", func(t *testing.T) {
518+
res := isCelo1Block(&params.ChainConfig{
519+
Cel2Time: nil,
520+
}, 1000)
521+
522+
assert.False(t, res)
523+
})
524+
525+
t.Run("Celo1", func(t *testing.T) {
526+
res := isCelo1Block(&params.ChainConfig{
527+
Cel2Time: &cel2Time,
528+
}, 500)
529+
530+
assert.True(t, res)
531+
})
532+
533+
t.Run("Celo2", func(t *testing.T) {
534+
res := isCelo1Block(&params.ChainConfig{
535+
Cel2Time: &cel2Time,
536+
}, 1000)
537+
538+
assert.False(t, res)
539+
})
540+
}
541+
542+
// TestRPCMarshalBlock_Celo1TotalDifficulty tests the RPCMarshalBlock function, specifically for totalDifficulty field
543+
// It validates the result has `totalDifficulty` field only if it's Celo1 block
544+
func TestRPCMarshalBlock_Celo1TotalDifficulty(t *testing.T) {
545+
t.Parallel()
546+
547+
blockTime := uint64(1000)
548+
block := types.NewBlock(&types.Header{Number: big.NewInt(100), Time: blockTime}, &types.Body{Transactions: []*types.Transaction{}}, nil, blocktest.NewHasher(), types.DefaultBlockConfig)
549+
550+
marshalBlock := func(t *testing.T, config *params.ChainConfig) map[string]interface{} {
551+
t.Helper()
552+
553+
resp, err := RPCMarshalBlock(context.Background(), block, false, false, config, testBackend{})
554+
if err != nil {
555+
require.NoError(t, err)
556+
}
557+
558+
return resp
559+
}
560+
561+
t.Run("Non-Celo", func(t *testing.T) {
562+
config := *params.MainnetChainConfig
563+
564+
res := marshalBlock(t, &config)
565+
566+
assert.Equal(t, nil, res["totalDifficulty"])
567+
})
568+
569+
t.Run("Celo1", func(t *testing.T) {
570+
expected := (*hexutil.Big)(new(big.Int).Add(block.Number(), common.Big1))
571+
572+
cel2Time := blockTime + 500
573+
config := *params.MainnetChainConfig
574+
config.Cel2Time = &cel2Time
575+
576+
res := marshalBlock(t, &config)
577+
578+
assert.Equal(t, expected, res["totalDifficulty"])
579+
})
580+
581+
t.Run("Celo2", func(t *testing.T) {
582+
cel2Time := blockTime - 500
583+
config := *params.MainnetChainConfig
584+
config.Cel2Time = &cel2Time
585+
586+
res := marshalBlock(t, &config)
587+
588+
assert.Equal(t, nil, res["totalDifficulty"])
589+
})
590+
}

0 commit comments

Comments
 (0)