Skip to content

Commit

Permalink
add -d and -o args for catchpointdump net, like file
Browse files Browse the repository at this point in the history
  • Loading branch information
cce committed Jan 25, 2025
1 parent d52e3dd commit 7162784
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 2 deletions.
1 change: 1 addition & 0 deletions cmd/catchpointdump/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ func init() {
rootCmd.AddCommand(fileCmd)
rootCmd.AddCommand(netCmd)
rootCmd.AddCommand(databaseCmd)
rootCmd.AddCommand(infoCmd)

Check warning on line 47 in cmd/catchpointdump/commands.go

View check run for this annotation

Codecov / codecov/patch

cmd/catchpointdump/commands.go#L47

Added line #L47 was not covered by tests
}

var rootCmd = &cobra.Command{
Expand Down
157 changes: 157 additions & 0 deletions cmd/catchpointdump/info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
// Copyright (C) 2019-2025 Algorand, Inc.
// This file is part of go-algorand
//
// go-algorand is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// go-algorand is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with go-algorand. If not, see <https://www.gnu.org/licenses/>.

package main

import (
"bufio"
"fmt"
"io"
"os"

"github.com/spf13/cobra"

"github.com/algorand/go-algorand/ledger"
"github.com/algorand/go-algorand/protocol"
)

var infoFile string

func init() {
infoCmd.Flags().StringVarP(&infoFile, "tar", "t", "", "Specify the catchpoint file (.tar or .tar.gz) to read")

Check warning on line 34 in cmd/catchpointdump/info.go

View check run for this annotation

Codecov / codecov/patch

cmd/catchpointdump/info.go#L33-L34

Added lines #L33 - L34 were not covered by tests
}

// infoCmd defines a new cobra command that only loads and prints the CatchpointFileHeader.
var infoCmd = &cobra.Command{
Use: "info",
Short: "Show header info from a catchpoint tar file",
Long: "Reads the specified catchpoint tar (or tar.gz) file, locates the content.json block, and prints the CatchpointFileHeader fields without loading the entire ledger.",
Args: validateNoPosArgsFn,
Run: func(cmd *cobra.Command, args []string) {
if infoFile == "" {
cmd.HelpFunc()(cmd, args)
return

Check warning on line 46 in cmd/catchpointdump/info.go

View check run for this annotation

Codecov / codecov/patch

cmd/catchpointdump/info.go#L43-L46

Added lines #L43 - L46 were not covered by tests
}
fi, err := os.Stat(infoFile)
if err != nil {
reportErrorf("Unable to stat file '%s': %v", infoFile, err)

Check warning on line 50 in cmd/catchpointdump/info.go

View check run for this annotation

Codecov / codecov/patch

cmd/catchpointdump/info.go#L48-L50

Added lines #L48 - L50 were not covered by tests
}
if fi.Size() == 0 {
reportErrorf("File '%s' is empty.", infoFile)

Check warning on line 53 in cmd/catchpointdump/info.go

View check run for this annotation

Codecov / codecov/patch

cmd/catchpointdump/info.go#L52-L53

Added lines #L52 - L53 were not covered by tests
}

// Open the catchpoint file
f, err := os.Open(infoFile)
if err != nil {
reportErrorf("Unable to open file '%s': %v", infoFile, err)

Check warning on line 59 in cmd/catchpointdump/info.go

View check run for this annotation

Codecov / codecov/patch

cmd/catchpointdump/info.go#L57-L59

Added lines #L57 - L59 were not covered by tests
}
defer f.Close()

Check warning on line 61 in cmd/catchpointdump/info.go

View check run for this annotation

Codecov / codecov/patch

cmd/catchpointdump/info.go#L61

Added line #L61 was not covered by tests

// Extract just the file header
fileHeader, err := loadCatchpointFileHeader(f, fi.Size())
if err != nil {
reportErrorf("Error reading CatchpointFileHeader from '%s': %v", infoFile, err)

Check warning on line 66 in cmd/catchpointdump/info.go

View check run for this annotation

Codecov / codecov/patch

cmd/catchpointdump/info.go#L64-L66

Added lines #L64 - L66 were not covered by tests
}

// Print out the fields (mimicking the logic in printAccountsDatabase, but simpler)
if fileHeader.Version == 0 {
fmt.Printf("No valid header was found.\n")
return

Check warning on line 72 in cmd/catchpointdump/info.go

View check run for this annotation

Codecov / codecov/patch

cmd/catchpointdump/info.go#L70-L72

Added lines #L70 - L72 were not covered by tests
}

fmt.Printf("Version: %d\n", fileHeader.Version)
fmt.Printf("Balances Round: %d\n", fileHeader.BalancesRound)
fmt.Printf("Block Round: %d\n", fileHeader.BlocksRound)
fmt.Printf("Block Header Digest: %s\n", fileHeader.BlockHeaderDigest.String())
fmt.Printf("Catchpoint: %s\n", fileHeader.Catchpoint)
fmt.Printf("Total Accounts: %d\n", fileHeader.TotalAccounts)
fmt.Printf("Total KVs: %d\n", fileHeader.TotalKVs)
fmt.Printf("Total Online Accounts: %d\n", fileHeader.TotalOnlineAccounts)
fmt.Printf("Total Online Round Params: %d\n", fileHeader.TotalOnlineRoundParams)
fmt.Printf("Total Chunks: %d\n", fileHeader.TotalChunks)

Check warning on line 84 in cmd/catchpointdump/info.go

View check run for this annotation

Codecov / codecov/patch

cmd/catchpointdump/info.go#L75-L84

Added lines #L75 - L84 were not covered by tests

totals := fileHeader.Totals
fmt.Printf("AccountTotals - Online Money: %d\n", totals.Online.Money.Raw)
fmt.Printf("AccountTotals - Online RewardUnits: %d\n", totals.Online.RewardUnits)
fmt.Printf("AccountTotals - Offline Money: %d\n", totals.Offline.Money.Raw)
fmt.Printf("AccountTotals - Offline RewardUnits: %d\n", totals.Offline.RewardUnits)
fmt.Printf("AccountTotals - Not Participating Money: %d\n", totals.NotParticipating.Money.Raw)
fmt.Printf("AccountTotals - Not Participating RewardUnits: %d\n", totals.NotParticipating.RewardUnits)
fmt.Printf("AccountTotals - Rewards Level: %d\n", totals.RewardsLevel)

Check warning on line 93 in cmd/catchpointdump/info.go

View check run for this annotation

Codecov / codecov/patch

cmd/catchpointdump/info.go#L86-L93

Added lines #L86 - L93 were not covered by tests
},
}

// loadCatchpointFileHeader reads only enough of the tar (or tar.gz) to
// decode the ledger.CatchpointFileHeader from the "content.json" chunk.
func loadCatchpointFileHeader(catchpointFile io.Reader, catchpointFileSize int64) (ledger.CatchpointFileHeader, error) {
var fileHeader ledger.CatchpointFileHeader
fmt.Printf("Scanning for CatchpointFileHeader in tar...\n\n")

Check warning on line 101 in cmd/catchpointdump/info.go

View check run for this annotation

Codecov / codecov/patch

cmd/catchpointdump/info.go#L99-L101

Added lines #L99 - L101 were not covered by tests

catchpointReader := bufio.NewReader(catchpointFile)
tarReader, _, err := getCatchpointTarReader(catchpointReader, catchpointFileSize)
if err != nil {
return fileHeader, err

Check warning on line 106 in cmd/catchpointdump/info.go

View check run for this annotation

Codecov / codecov/patch

cmd/catchpointdump/info.go#L103-L106

Added lines #L103 - L106 were not covered by tests
}

for {
hdr, err := tarReader.Next()
if err != nil {
if err == io.EOF {

Check warning on line 112 in cmd/catchpointdump/info.go

View check run for this annotation

Codecov / codecov/patch

cmd/catchpointdump/info.go#L109-L112

Added lines #L109 - L112 were not covered by tests
// We reached the end without finding content.json
break

Check warning on line 114 in cmd/catchpointdump/info.go

View check run for this annotation

Codecov / codecov/patch

cmd/catchpointdump/info.go#L114

Added line #L114 was not covered by tests
}
return fileHeader, err

Check warning on line 116 in cmd/catchpointdump/info.go

View check run for this annotation

Codecov / codecov/patch

cmd/catchpointdump/info.go#L116

Added line #L116 was not covered by tests
}

// We only need the "content.json" file
if hdr.Name == ledger.CatchpointContentFileName {

Check warning on line 120 in cmd/catchpointdump/info.go

View check run for this annotation

Codecov / codecov/patch

cmd/catchpointdump/info.go#L120

Added line #L120 was not covered by tests
// Read exactly hdr.Size bytes
buf := make([]byte, hdr.Size)
_, readErr := io.ReadFull(tarReader, buf)
if readErr != nil && readErr != io.EOF {
return fileHeader, readErr

Check warning on line 125 in cmd/catchpointdump/info.go

View check run for this annotation

Codecov / codecov/patch

cmd/catchpointdump/info.go#L122-L125

Added lines #L122 - L125 were not covered by tests
}

// Decode into fileHeader
readErr = protocol.Decode(buf, &fileHeader)
if readErr != nil {
return fileHeader, readErr

Check warning on line 131 in cmd/catchpointdump/info.go

View check run for this annotation

Codecov / codecov/patch

cmd/catchpointdump/info.go#L129-L131

Added lines #L129 - L131 were not covered by tests
}
// Once we have the fileHeader, we can break out.
// If you wanted to keep scanning, you could keep going,
// but it’s not needed just for the header.
return fileHeader, nil

Check warning on line 136 in cmd/catchpointdump/info.go

View check run for this annotation

Codecov / codecov/patch

cmd/catchpointdump/info.go#L136

Added line #L136 was not covered by tests
}

// Otherwise skip this chunk
skipBytes := hdr.Size
n, err := io.Copy(io.Discard, tarReader)
if err != nil {
return fileHeader, err

Check warning on line 143 in cmd/catchpointdump/info.go

View check run for this annotation

Codecov / codecov/patch

cmd/catchpointdump/info.go#L140-L143

Added lines #L140 - L143 were not covered by tests
}

// skip any leftover in case we didn't read the entire chunk
if skipBytes > n {

Check warning on line 147 in cmd/catchpointdump/info.go

View check run for this annotation

Codecov / codecov/patch

cmd/catchpointdump/info.go#L147

Added line #L147 was not covered by tests
// keep discarding until we've skipped skipBytes total
_, err := io.CopyN(io.Discard, tarReader, skipBytes-n)
if err != nil {
return fileHeader, err

Check warning on line 151 in cmd/catchpointdump/info.go

View check run for this annotation

Codecov / codecov/patch

cmd/catchpointdump/info.go#L149-L151

Added lines #L149 - L151 were not covered by tests
}
}
}
// If we get here, we never found the content.json entry
return fileHeader, nil

Check warning on line 156 in cmd/catchpointdump/info.go

View check run for this annotation

Codecov / codecov/patch

cmd/catchpointdump/info.go#L156

Added line #L156 was not covered by tests
}
11 changes: 9 additions & 2 deletions cmd/catchpointdump/net.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ func init() {
netCmd.Flags().BoolVarP(&singleCatchpoint, "single", "s", true, "Download/process only from a single relay")
netCmd.Flags().BoolVarP(&loadOnly, "load", "l", false, "Load only, do not dump")
netCmd.Flags().VarP(excludedFields, "exclude-fields", "e", "List of fields to exclude from the dump: ["+excludedFields.AllowedString()+"]")
netCmd.Flags().StringVarP(&outFileName, "output", "o", "", "Specify an outfile for the dump ( i.e. tracker.dump.txt )")
netCmd.Flags().BoolVarP(&printDigests, "digest", "d", false, "Print balances and spver digests")

Check warning on line 64 in cmd/catchpointdump/net.go

View check run for this annotation

Codecov / codecov/patch

cmd/catchpointdump/net.go#L63-L64

Added lines #L63 - L64 were not covered by tests
}

var netCmd = &cobra.Command{
Expand Down Expand Up @@ -103,7 +105,7 @@ var netCmd = &cobra.Command{
reportInfof("failed to load/dump from tar file for '%s' : %v", addr, err)
continue
}
// clear possible errors from previous run: at this point we've been succeed
// clear possible errors from previous run: at this point we've succeeded
err = nil
if singleCatchpoint {
// a catchpoint processes successfully, exit if needed
Expand Down Expand Up @@ -348,7 +350,12 @@ func loadAndDump(addr string, tarFile string, genesisInitState ledgercore.InitSt

if !loadOnly {
dirName := "./" + strings.Split(networkName, ".")[0] + "/" + strings.Split(addr, ".")[0]
outFile, err := os.OpenFile(dirName+"/"+strconv.FormatUint(uint64(round), 10)+".dump", os.O_RDWR|os.O_TRUNC|os.O_CREATE, 0755)
// If user provided -o <filename>, use that; otherwise use <dirName>/<round>.dump
dumpFilename := outFileName
if dumpFilename == "" {
dumpFilename = dirName + "/" + strconv.FormatUint(uint64(round), 10) + ".dump"

Check warning on line 356 in cmd/catchpointdump/net.go

View check run for this annotation

Codecov / codecov/patch

cmd/catchpointdump/net.go#L354-L356

Added lines #L354 - L356 were not covered by tests
}
outFile, err := os.OpenFile(dumpFilename, os.O_RDWR|os.O_TRUNC|os.O_CREATE, 0755)

Check warning on line 358 in cmd/catchpointdump/net.go

View check run for this annotation

Codecov / codecov/patch

cmd/catchpointdump/net.go#L358

Added line #L358 was not covered by tests
if err != nil {
return err
}
Expand Down

0 comments on commit 7162784

Please sign in to comment.