Skip to content

Commit

Permalink
implemented methods: eth_getHeaderByNumber
Browse files Browse the repository at this point in the history
eth_getHeaderByHash.
  • Loading branch information
novosandara committed Mar 8, 2024
1 parent 9a23b66 commit 07ada94
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 0 deletions.
53 changes: 53 additions & 0 deletions jsonrpc/eth_blockchain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,59 @@ func TestEth_Block_GetBlockByHash(t *testing.T) {
assert.Nil(t, res)
}

func TestEth_Block_GetHeaderByNumber(t *testing.T) {
store := &mockBlockStore{}
for i := 0; i < 10; i++ {
store.add(newTestBlock(uint64(i), hash1))
}

eth := newTestEthEndpoint(store)

cases := []struct {
description string
blockNum BlockNumber
isNotNil bool
err bool
}{
{"should be able to get the latest block number", LatestBlockNumber, true, false},
{"should be able to get the earliest block number", EarliestBlockNumber, true, false},
{"should not be able to get block with negative number", BlockNumber(-50), false, true},
{"should be able to get block with number 0", BlockNumber(0), true, false},
{"should be able to get block with number 2", BlockNumber(2), true, false},
{"should be able to get block with number greater than latest block", BlockNumber(50), false, false},
}
for _, c := range cases {
res, err := eth.GetHeadarByNumber(c.blockNum)

if c.isNotNil {
assert.NotNil(t, res, "expected to return block, but got nil")
} else {
assert.Nil(t, res, "expected to return nil, but got data")
}

if c.err {
assert.Error(t, err)
} else {
assert.NoError(t, err)
}
}
}

func TestEth_Block_GetHeaderByHash(t *testing.T) {
store := &mockBlockStore{}
store.add(newTestBlock(1, hash1))

eth := newTestEthEndpoint(store)

res, err := eth.GetHeadarByHash(hash1)
assert.NoError(t, err)
assert.NotNil(t, res)

res, err = eth.GetHeadarByHash(hash2)
assert.NoError(t, err)
assert.Nil(t, res)
}

func TestEth_Block_BlockNumber(t *testing.T) {
store := &mockBlockStore{}
store.add(&types.Block{
Expand Down
35 changes: 35 additions & 0 deletions jsonrpc/eth_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,41 @@ func (e *Eth) GetBlockByHash(hash types.Hash, fullTx bool) (interface{}, error)
return toBlock(block, fullTx), nil
}

// GetHeaderByNumber returns the requested canonical block header.
// * When blockNr is -1 the chain head is returned.
// * When blockNr is -2 the pending chain head is returned.
func (e *Eth) GetHeadarByNumber(number BlockNumber) (interface{}, error) {
num, err := GetNumericBlockNumber(number, e.store)
if err != nil {
return nil, err
}

block, ok := e.store.GetBlockByNumber(num, true)
if !ok {
return nil, nil
}

if err := e.filterExtra(block); err != nil {
return nil, err
}

return toHeader(block.Header), nil
}

// GetHeaderByHash returns the requested header by hash.
func (e *Eth) GetHeadarByHash(hash types.Hash) (interface{}, error) {
block, ok := e.store.GetBlockByHash(hash, true)
if !ok {
return nil, nil
}

if err := e.filterExtra(block); err != nil {
return nil, err
}

return toHeader(block.Header), nil
}

func (e *Eth) filterExtra(block *types.Block) error {
// we need to copy it because the store returns header from storage directly
// and not a copy, so changing it, actually changes it in storage as well
Expand Down
46 changes: 46 additions & 0 deletions jsonrpc/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,27 @@ func toTransaction(
return res
}

type header struct {
ParentHash types.Hash `json:"parentHash"`
Sha3Uncles types.Hash `json:"sha3Uncles"`
Miner argBytes `json:"miner"`
StateRoot types.Hash `json:"stateRoot"`
TxRoot types.Hash `json:"transactionsRoot"`
ReceiptsRoot types.Hash `json:"receiptsRoot"`
LogsBloom types.Bloom `json:"logsBloom"`
Difficulty argUint64 `json:"difficulty"`
TotalDifficulty argUint64 `json:"totalDifficulty"`
Number argUint64 `json:"number"`
GasLimit argUint64 `json:"gasLimit"`
GasUsed argUint64 `json:"gasUsed"`
Timestamp argUint64 `json:"timestamp"`
ExtraData argBytes `json:"extraData"`
MixHash types.Hash `json:"mixHash"`
Nonce types.Nonce `json:"nonce"`
Hash types.Hash `json:"hash"`
BaseFee argUint64 `json:"baseFeePerGas,omitempty"`
}

type block struct {
ParentHash types.Hash `json:"parentHash"`
Sha3Uncles types.Hash `json:"sha3Uncles"`
Expand Down Expand Up @@ -198,6 +219,31 @@ func toBlock(b *types.Block, fullTx bool) *block {
return res
}

func toHeader(h *types.Header) *header {
res := &header{
ParentHash: h.ParentHash,
Sha3Uncles: h.Sha3Uncles,
Miner: argBytes(h.Miner),
StateRoot: h.StateRoot,
TxRoot: h.TxRoot,
ReceiptsRoot: h.ReceiptsRoot,
LogsBloom: h.LogsBloom,
Difficulty: argUint64(h.Difficulty),
TotalDifficulty: argUint64(h.Difficulty), // not needed for POS
Number: argUint64(h.Number),
GasLimit: argUint64(h.GasLimit),
GasUsed: argUint64(h.GasUsed),
Timestamp: argUint64(h.Timestamp),
ExtraData: argBytes(h.ExtraData),
MixHash: h.MixHash,
Nonce: h.Nonce,
Hash: h.Hash,
BaseFee: argUint64(h.BaseFee),
}

return res
}

type receipt struct {
Root types.Hash `json:"root"`
CumulativeGasUsed argUint64 `json:"cumulativeGasUsed"`
Expand Down

0 comments on commit 07ada94

Please sign in to comment.