Skip to content

Commit

Permalink
Clean up print block
Browse files Browse the repository at this point in the history
  • Loading branch information
jubeless committed Dec 4, 2023
1 parent 2e7b9f9 commit 57af3fd
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 58 deletions.
4 changes: 3 additions & 1 deletion chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,10 @@ type Chain[B Block] struct {
//
BlockEncoder BlockEncoder

//
RegisterSubstreamsExtensions func(chain *Chain[B]) ([]SubstreamsExtension, error)

// CoreBinaryEnabled is a flag that when set to true indicates that `firecore` binary is being run directly? (not through firexxx)
CoreBinaryEnabled bool
}

type ToolsConfig[B Block] struct {
Expand Down
1 change: 1 addition & 0 deletions cmd/firecore/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ func main() {
FullyQualifiedModule: "github.com/streamingfast/firehose-core",
Version: version,
BlockFactory: func() firecore.Block { return new(pbbstream.Block) },
CoreBinaryEnabled: true,
ConsoleReaderFactory: firecore.NewConsoleReader,
Tools: &firecore.ToolsConfig[*pbbstream.Block]{},
})
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -223,4 +223,6 @@ require (
replace (
github.com/ShinyTrinkets/overseer => github.com/streamingfast/overseer v0.2.1-0.20210326144022-ee491780e3ef
github.com/bytecodealliance/wasmtime-go/v4 => github.com/streamingfast/wasmtime-go/v4 v4.0.0-freemem3
github.com/streamingfast/bstream => ../bstream
)

5 changes: 4 additions & 1 deletion tools.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,10 @@ func getFirehoseClientFromCmd[B Block, C any](cmd *cobra.Command, logger *zap.Lo
requestInfo.GRPCCallOpts = append(requestInfo.GRPCCallOpts, compressor)
}

requestInfo.Transforms, err = chain.Tools.TransformFlags.Parse(cmd, logger)
if chain.Tools.TransformFlags != nil {
requestInfo.Transforms, err = chain.Tools.TransformFlags.Parse(cmd, logger)
}

if err != nil {
return firehoseClient, nil, nil, fmt.Errorf("unable to parse transforms flags: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion tools_check_blocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ func validateBlockSegment[B Block](
seenBlockCount++

if printDetails == PrintStats {
err := block.PrintBlock(false, os.Stdout)
err := printBlock(block, false, os.Stdout)
if err != nil {
fmt.Printf("❌ Unable to print block %s: %s\n", block.AsRef(), err)
continue
Expand Down
95 changes: 68 additions & 27 deletions tools_print.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func createToolsPrintMergedBlocksE[B Block](chain *Chain[B]) CommandExecutor {

seenBlockCount++

if err := printBlock(block, chain, outputMode, printTransactions, dPrinter); err != nil {
if err := displayBlock(block, chain, outputMode, printTransactions, dPrinter); err != nil {
// Error is ready to be passed to the user as-is
return err
}
Expand Down Expand Up @@ -200,7 +200,7 @@ func createToolsPrintOneBlockE[B Block](chain *Chain[B]) CommandExecutor {
return fmt.Errorf("reading block: %w", err)
}

if err := printBlock(block, chain, outputMode, printTransactions, dPrinter); err != nil {
if err := displayBlock(block, chain, outputMode, printTransactions, dPrinter); err != nil {
// Error is ready to be passed to the user as-is
return err
}
Expand All @@ -224,13 +224,14 @@ func toolsPrintCmdGetOutputMode(cmd *cobra.Command) (PrintOutputMode, error) {
return out, nil
}

func printBlock[B Block](pbBlock *pbbstream.Block, chain *Chain[B], outputMode PrintOutputMode, printTransactions bool, dPrinter *dynamicPrinter) error {
func displayBlock[B Block](pbBlock *pbbstream.Block, chain *Chain[B], outputMode PrintOutputMode, printTransactions bool, dPrinter *dynamicPrinter) error {
if pbBlock == nil {
return fmt.Errorf("block is nil")
}

switch outputMode {
case PrintOutputModeText:
err := pbBlock.PrintBlock(printTransactions, os.Stdout)
err := printBlock(pbBlock, printTransactions, os.Stdout)
if err != nil {
return fmt.Errorf("pbBlock text printing: %w", err)
}
Expand Down Expand Up @@ -258,32 +259,35 @@ func printBlock[B Block](pbBlock *pbbstream.Block, chain *Chain[B], outputMode P
)
}

var marshallableBlock Block = pbBlock
chainBlock := chain.BlockFactory()
isLegacyBlock := chainBlock == nil
if isLegacyBlock {
err := proto.Unmarshal(pbBlock.GetPayloadBuffer(), chainBlock)
if err != nil {
return fmt.Errorf("unmarshalling legacy pb block : %w", err)
isLegacyBlock := pbBlock.Payload == nil
if chain.CoreBinaryEnabled {
// since we are running directly the firecore binary we will *NOT* use the BlockFactory

if isLegacyBlock {
return dPrinter.printBlock(legacyKindsToProtoType(pbBlock.PayloadKind), pbBlock.GetPayloadBuffer(), encoder, marshallers)
}
marshallableBlock = chainBlock

} else if _, ok := chainBlock.(*pbbstream.Block); ok {
return dPrinter.printBlock(pbBlock, encoder, marshallers)
return dPrinter.printBlock(pbBlock.Payload.TypeUrl, pbBlock.Payload.Value, encoder, marshallers)

} else {
marshallableBlock = chainBlock
// since we are running via the chain specific binary (i.e. fireeth) we can use a BlockFactory
marshallableBlock := chain.BlockFactory()
if isLegacyBlock {
if err := proto.Unmarshal(pbBlock.GetPayloadBuffer(), marshallableBlock); err != nil {
return fmt.Errorf("unmarshal legacy block payload to protocol block: %w", err)
}
} else {
if err := pbBlock.Payload.UnmarshalTo(marshallableBlock); err != nil {
return fmt.Errorf("pbBlock payload unmarshal: %w", err)
}
}

err := pbBlock.Payload.UnmarshalTo(marshallableBlock)
err := json.MarshalEncode(encoder, marshallableBlock, json.WithMarshalers(marshallers))
if err != nil {
return fmt.Errorf("pbBlock payload unmarshal: %w", err)
return fmt.Errorf("pbBlock JSON printing: json marshal: %w", err)
}
}

err := json.MarshalEncode(encoder, marshallableBlock, json.WithMarshalers(marshallers))
if err != nil {
return fmt.Errorf("pbBlock JSON printing: json marshal: %w", err)
}
}

return nil
Expand All @@ -303,12 +307,12 @@ func newDynamicPrinter(importPaths []string) (*dynamicPrinter, error) {
}, nil
}

func (d *dynamicPrinter) printBlock(block *pbbstream.Block, encoder *jsontext.Encoder, marshalers *json.Marshalers) error {
func (d *dynamicPrinter) printBlock(blkTypeURL string, blkPayload []byte, encoder *jsontext.Encoder, marshalers *json.Marshalers) error {
for _, fd := range d.fileDescriptors {
md := fd.FindSymbol(block.Payload.TypeUrl)
md := fd.FindSymbol(blkTypeURL)
if md != nil {
dynMsg := dynamic.NewMessageFactoryWithDefaults().NewDynamicMessage(md.(*desc.MessageDescriptor))
if err := dynMsg.Unmarshal(block.Payload.Value); err != nil {
if err := dynMsg.Unmarshal(blkPayload); err != nil {
return fmt.Errorf("unmarshalling block: %w", err)
}
err := json.MarshalEncode(encoder, dynMsg, json.WithMarshalers(marshalers))
Expand All @@ -318,7 +322,7 @@ func (d *dynamicPrinter) printBlock(block *pbbstream.Block, encoder *jsontext.En
return nil
}
}
return fmt.Errorf("no message descriptor in proto paths for type url %q", block.Payload.TypeUrl)
return fmt.Errorf("no message descriptor in proto paths for type url %q", blkTypeURL)
}

func parseProtoFiles(importPaths []string) (fds []*desc.FileDescriptor, err error) {
Expand Down Expand Up @@ -347,8 +351,6 @@ func parseProtoFiles(importPaths []string) (fds []*desc.FileDescriptor, err erro
ip = append(ip, importPath)
}

fmt.Println("importPaths", importPaths)

parser := protoparse.Parser{
ImportPaths: ip,
}
Expand Down Expand Up @@ -377,3 +379,42 @@ func parseProtoFiles(importPaths []string) (fds []*desc.FileDescriptor, err erro
return

}

func printBlock(b *pbbstream.Block, printTransactions bool, out io.Writer) error {
_, err := out.Write(
[]byte(
fmt.Sprintf(
"Block #%d (%s)\n",
b.Number,
b.Id,
),
),
)
if err != nil {
return fmt.Errorf("writing block: %w", err)
}

if printTransactions {
if _, err = out.Write([]byte("warning: transaction printing not supported by bstream block")); err != nil {
return fmt.Errorf("writing transaction support warning: %w", err)
}
}

return nil
}

func legacyKindsToProtoType(protocol pbbstream.Protocol) string {
switch protocol {
case pbbstream.Protocol_EOS:
return "sf.antelope.type.v1.Block"
case pbbstream.Protocol_ETH:
return "sf.ethereum.type.v2.Block"
case pbbstream.Protocol_SOLANA:
return "sf.solana.type.v1.Block"
case pbbstream.Protocol_NEAR:
return "sf.near.type.v1.Block"
case pbbstream.Protocol_COSMOS:
return "sf.cosmos.type.v1.Block"
}
panic("unaligned protocol")
}
28 changes: 0 additions & 28 deletions types.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package firecore

import (
"fmt"
"io"
"time"

"github.com/spf13/cobra"
Expand Down Expand Up @@ -63,33 +62,6 @@ type Block interface {
// GetFirehoseBlockTime returns the block timestamp as a time.Time of when the block was
// produced. This should the consensus agreed time of the block.
GetFirehoseBlockTime() time.Time

// PrintBlock is printing function that render a chain specific human readable
// form Block. This block is expected to be rendered as
// a single line for example on Ethereum rendering of a single block looks like:
//
// ```
// Block #24924194 (01d6d349fbd3fa419182a2f0cf0b00714e101286650c239de8923caef6134b6c) 62 transactions, 607 calls
// ```
//
// If the [alsoPrintTransactions] argument is true, each transaction of the block should also be printed, following
// directly the block line. Each transaction should also be on a single line, usually prefixed with a `- ` to make
// the rendering more appealing.
//
// For example on Ethereum rendering with [alsoPrintTransactions] being `true` looks like:
//
// ```
// Block #24924194 (01d6d349fbd3fa419182a2f0cf0b00714e101286650c239de8923caef6134b6c) 62 transactions, 607 calls
// - Transaction 0xc7e04240d6f2cc5f382c478fd0a0b5c493463498c64b31477b95bded8cd12ab4 (10 calls)
// - Transaction 0xc7d8a698351eb1ac64acb76c8bf898365bb639865271add95d2c81650b2bd98c (4 calls)
// ```
//
// The `out` parameter is used to write to the correct location. You can use [fmt.Fprintf] and [fmt.Fprintln]
// and use `out` as the output writer in your implementation.
//
// The [BlockPrinter] is optional, if nil, a default block printer will be used. It's important to note
// that the default block printer error out if `alsoPrintTransactions` is true.
PrintBlock(printTransactions bool, out io.Writer) error
}

// BlockLIBNumDerivable is an optional interface that can be implemented by your chain's block model Block
Expand Down

0 comments on commit 57af3fd

Please sign in to comment.