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 }