github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/pkg/rpc/get_block_header.go (about)

     1  // Copyright 2021 The TrueBlocks Authors. All rights reserved.
     2  // Use of this source code is governed by a license that can
     3  // be found in the LICENSE file.
     4  
     5  package rpc
     6  
     7  import (
     8  	"fmt"
     9  
    10  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/base"
    11  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/rpc/query"
    12  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/types"
    13  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/walk"
    14  	"github.com/ethereum/go-ethereum"
    15  )
    16  
    17  // GetBlockHeaderByNumber fetches the block with only transactions' hashes from the RPC
    18  func (conn *Connection) GetBlockHeaderByNumber(bn base.Blknum) (types.LightBlock, error) {
    19  	if conn.StoreReadable() && bn != base.NOPOSN {
    20  		// walk.Cache_Blocks
    21  		block := types.LightBlock{
    22  			BlockNumber: bn,
    23  		}
    24  		if err := conn.Store.Read(&block, nil); err == nil {
    25  			// read was successful
    26  			return block, nil
    27  		}
    28  	}
    29  
    30  	block, err := conn.getLightBlockFromRpc(bn, notAHash)
    31  	if err != nil {
    32  		return types.LightBlock{}, err
    33  	}
    34  
    35  	isFinal := base.IsFinal(conn.LatestBlockTimestamp, block.Timestamp)
    36  	if isFinal && conn.StoreWritable() && conn.EnabledMap[walk.Cache_Blocks] {
    37  		_ = conn.Store.Write(block, nil)
    38  	}
    39  
    40  	// TODO: BOGUS - avoid copies
    41  	return *block, nil
    42  }
    43  
    44  // getLightBlockFromRpc returns the block as received from the node
    45  func (conn *Connection) getLightBlockFromRpc(bn base.Blknum, hash base.Hash) (*types.LightBlock, error) {
    46  	method := "eth_getBlockByNumber"
    47  	params := query.Params{fmt.Sprintf("0x%x", bn), false}
    48  	if bn == base.NOPOSN {
    49  		params = query.Params{"latest", false}
    50  	}
    51  	if !hash.IsZero() {
    52  		method = "eth_getBlockByHash"
    53  		params = query.Params{hash, false}
    54  	}
    55  
    56  	if block, err := query.Query[types.LightBlock](conn.Chain, method, params); err != nil {
    57  		return &types.LightBlock{}, err
    58  	} else {
    59  		block.BlockNumber = block.Number
    60  		if bn == 0 {
    61  			// TODO: Chain specific
    62  			block.Timestamp = conn.GetBlockTimestamp(1) - 13
    63  		} else if block.Timestamp == 0 {
    64  			return &types.LightBlock{}, fmt.Errorf("block at %s returned an error: %w", fmt.Sprintf("%d", bn), ethereum.NotFound)
    65  		}
    66  		for i := 0; i < len(block.Withdrawals); i++ {
    67  			block.Withdrawals[i].BlockNumber = block.BlockNumber
    68  			block.Withdrawals[i].Timestamp = block.Timestamp
    69  		}
    70  		return block, nil
    71  	}
    72  }