Skip to content

Commit

Permalink
adding v1_old block proto to fix transaction status and transaction h…
Browse files Browse the repository at this point in the history
…ash and update tools documentation
  • Loading branch information
Eduard-Voiculescu committed Jan 23, 2025
1 parent 99613f8 commit 23f4caf
Show file tree
Hide file tree
Showing 12 changed files with 2,668 additions and 20 deletions.
1 change: 1 addition & 0 deletions cmd/firestellar/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func init() {
rootCmd.AddCommand(NewToolIssueAssetCmd())
rootCmd.AddCommand(NewToolSendPaymentAssetCmd())
rootCmd.AddCommand(NewToolDecodeSeedCmd())
rootCmd.AddCommand(NewToolFixBlocksCmd())
}

func main() {
Expand Down
2 changes: 1 addition & 1 deletion cmd/firestellar/tool_create_account.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
func NewToolCreateAccountCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "tool-create-account",
Short: "Firehose Stellar tool to an create account",
Short: "Tool to create account",
Args: cobra.ExactArgs(0),
RunE: toolCreateAccountRunE,
}
Expand Down
17 changes: 8 additions & 9 deletions cmd/firestellar/tool_decode_block.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package main

import (
"encoding/base64"
"encoding/hex"
"errors"
"fmt"
Expand All @@ -25,7 +24,7 @@ import (
func NewToolDecodeBlockCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "tool-decode-block <store> <block-range>",
Short: "Firehose Stellar tool to decode a firehose block",
Short: "Tool to decode a firehose block",
Args: cobra.ExactArgs(2),
RunE: runDecodeBlockE,
}
Expand Down Expand Up @@ -148,14 +147,14 @@ func marshalTransaction(e *jsontext.Encoder, value *pbstellar.Transaction, optio
ResultXdr *xdrTypes.TransactionResult
}

// FIXME: once the transaction hash is fixed, we can remove this
fixHash := base64.StdEncoding.EncodeToString(value.Hash)
fixHashB, err := hex.DecodeString(fixHash)
if err != nil {
return fmt.Errorf("unable to decode hash: %w", err)
}
// // FIXME: once the transaction hash is fixed, we can remove this
// fixHash := base64.StdEncoding.EncodeToString(value.Hash)
// fixHashB, err := hex.DecodeString(fixHash)
// if err != nil {
// return fmt.Errorf("unable to decode hash: %w", err)
// }
trx := &DecodedTransaction{
Hash: fixHashB,
Hash: value.Hash,
Status: value.Status,
CreatedAt: value.CreatedAt,
ApplicationOrder: value.ApplicationOrder,
Expand Down
2 changes: 1 addition & 1 deletion cmd/firestellar/tool_decode_seed.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
func NewToolDecodeSeedCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "tool-decode-seed <seed>",
Short: "Firehose Stellar tool to decode seed",
Short: "Tool to decode seed",
Args: cobra.ExactArgs(1),
RunE: toolDecodeSeedRunE,
}
Expand Down
192 changes: 192 additions & 0 deletions cmd/firestellar/tool_fix_blocks.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
package main

import (
"encoding/base64"
"encoding/hex"
"errors"
"fmt"
"io"
"os"
"strconv"

"github.com/spf13/cobra"
"github.com/streamingfast/bstream"
"github.com/streamingfast/dstore"
firecore "github.com/streamingfast/firehose-core"
pbstellarv1 "github.com/streamingfast/firehose-stellar/pb/sf/stellar/type/v1"
pbstellarv1_old "github.com/streamingfast/firehose-stellar/pb/sf/stellar/type/v1_old"
"github.com/streamingfast/firehose-stellar/utils"

"go.uber.org/zap"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/anypb"
)

func NewToolFixBlocksCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "tool-fix-blocks <first-streamable-block> <stop-block> <src-store-url> <dst-store-url>",
Short: "Tool to fix blocks",
Args: cobra.ExactArgs(4),
RunE: toolFixBlockRunE,
}
return cmd
}

func toolFixBlockRunE(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
firstStreamableBlock, err := strconv.ParseUint(args[0], 10, 64)
if err != nil {
return fmt.Errorf("converting first streamable block to uint64: %w", err)
}

stopBlock, err := strconv.ParseUint(args[1], 10, 64)
if err != nil {
return fmt.Errorf("converting stop block to uint64: %w", err)
}

srcStore, err := dstore.NewDBinStore(args[2])
if err != nil {
return fmt.Errorf("unable to create source store: %w", err)
}

destStore, err := dstore.NewDBinStore(args[3])
if err != nil {
return fmt.Errorf("unable to create destination store: %w", err)
}

logger.Debug(
"starting fix unknown type blocks",
zap.String("source_blocks_store", srcStore.BaseURL().String()),
zap.String("destination_blocks_store", destStore.BaseURL().String()),
zap.Uint64("first_streamable_block", firstStreamableBlock),
zap.Uint64("stop_block", stopBlock),
)

mergeWriter := &firecore.MergedBlocksWriter{
Store: destStore,
LowBlockNum: firstStreamableBlock,
StopBlockNum: stopBlock,
Logger: logger,
Cmd: cmd,
}
var lastFilename string
var blockCount = 0
err = srcStore.WalkFrom(ctx, "", fmt.Sprintf("%010d", firstStreamableBlock), func(filename string) error {
var fileReader io.Reader
fileReader, err = srcStore.OpenObject(ctx, filename)
if err != nil {
return fmt.Errorf("creating reader: %w", err)
}

var blockReader *bstream.DBinBlockReader
blockReader, err = bstream.NewDBinBlockReader(fileReader)
if err != nil {
return fmt.Errorf("creating block reader: %w", err)
}

// the source store is a merged file store
for {
currentBlock, err := blockReader.Read()
if err != nil {
if err == io.EOF {
fmt.Fprintf(os.Stderr, "Total blocks: %d\n", blockCount)
break
}
return fmt.Errorf("error receiving blocks: %w", err)
}

blockCount++

stellarBlock := &pbstellarv1_old.Block{}
err = proto.Unmarshal(currentBlock.Payload.Value, stellarBlock)
if err != nil {
return fmt.Errorf("unmarshaling block: %w", err)
}

convertedTransactions, err := convertOldTransactions(stellarBlock.Transactions)
if err != nil {
return fmt.Errorf("converting old transactions: %w", err)
}

fixedStellarBlock := &pbstellarv1.Block{
Number: stellarBlock.Number,
Hash: stellarBlock.Hash,
Header: convertOldHeader(stellarBlock.Header),
Transactions: convertedTransactions,
CreatedAt: stellarBlock.CreatedAt,
}

payload, err := anypb.New(fixedStellarBlock)
if err != nil {
return fmt.Errorf("creating payload: %w", err)
}

currentBlock.Payload = payload
if err = mergeWriter.ProcessBlock(currentBlock, nil); err != nil {
return fmt.Errorf("processing block: %w", err)
}
}

lastFilename = filename
return nil
})

mergeWriter.Logger = mergeWriter.Logger.With(zap.String("last_filename", lastFilename), zap.Int("block_count", blockCount))
if err != nil {
if errors.Is(err, dstore.StopIteration) {
err = mergeWriter.WriteBundle()
if err != nil {
return fmt.Errorf("writing bundle: %w", err)
}
fmt.Println("done")
return nil
}
if errors.Is(err, io.EOF) {
fmt.Println("done")
return nil
}
return fmt.Errorf("walking source store: %w", err)
}

fmt.Println("Done fixing blocks")
return nil
}

func convertOldHeader(oldHeader *pbstellarv1_old.Header) *pbstellarv1.Header {
return &pbstellarv1.Header{
LedgerVersion: oldHeader.LedgerVersion,
PreviousLedgerHash: oldHeader.PreviousLedgerHash,
TotalCoins: oldHeader.TotalCoins,
BaseFee: oldHeader.BaseFee,
BaseReserve: oldHeader.BaseReserve,
}
}

func convertOldTransactions(oldTransactions []*pbstellarv1_old.Transaction) ([]*pbstellarv1.Transaction, error) {
var transactions []*pbstellarv1.Transaction
for _, oldTransaction := range oldTransactions {
convertedTransaction, err := convertOldTransaction(oldTransaction)
if err != nil {
return nil, fmt.Errorf("converting transaction: %w", err)
}
transactions = append(transactions, convertedTransaction)
}
return transactions, nil
}

func convertOldTransaction(oldTransaction *pbstellarv1_old.Transaction) (*pbstellarv1.Transaction, error) {
fixHash := base64.StdEncoding.EncodeToString(oldTransaction.Hash)
txHashbytes, err := hex.DecodeString(fixHash)
if err != nil {
return nil, fmt.Errorf("decoding transaction hash: %w", err)
}
return &pbstellarv1.Transaction{
Hash: txHashbytes,
Status: utils.ConvertTransactionStatus(oldTransaction.Status),
CreatedAt: oldTransaction.CreatedAt,
ApplicationOrder: oldTransaction.ApplicationOrder,
EnvelopeXdr: oldTransaction.EnvelopeXdr,
ResultMetaXdr: oldTransaction.ResultMetaXdr,
ResultXdr: oldTransaction.ResultXdr,
}, nil
}
2 changes: 1 addition & 1 deletion cmd/firestellar/tool_issue_asset.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
func NewToolIssueAssetCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "tool-issue-asset <issuer-account-seed> <distributor-account-seed> <token-code>",
Short: "Firehose Stellar tool to issue asset",
Short: "Tool to issue asset",
Args: cobra.ExactArgs(3),
RunE: toolIssueAssetRunE,
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/firestellar/tool_send_payment.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
func NewToolSendPaymentCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "tool-send-payment <source-account-seed> <destination-account> <amount>",
Short: "Firehose Stellar tool to send payment",
Short: "Tool to send payment",
Args: cobra.ExactArgs(3),
RunE: toolSendPaymentRunE,
Example: cli.Dedent(`
Expand Down
2 changes: 1 addition & 1 deletion cmd/firestellar/tool_send_payment_asset.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
func NewToolSendPaymentAssetCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "tool-send-payment-asset <issuer-seed> <accound-dest-pk> <asset-code> <amount>",
Short: "Firehose Stellar tool to send payment",
Short: "Tool to send payment",
Args: cobra.ExactArgs(4),
RunE: toolSendPaymentAssetRunE,
Example: cli.Dedent(`
Expand Down
Loading

0 comments on commit 23f4caf

Please sign in to comment.