140 lines
5.0 KiB
Go
140 lines
5.0 KiB
Go
/*
|
|
Copyright IBM Corp. All Rights Reserved.
|
|
|
|
SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/hyperledger/fabric/internal/ledgerutil/compare"
|
|
"github.com/hyperledger/fabric/internal/ledgerutil/identifytxs"
|
|
"github.com/hyperledger/fabric/internal/ledgerutil/verify"
|
|
"gopkg.in/alecthomas/kingpin.v2"
|
|
)
|
|
|
|
const (
|
|
compareErrorMessage = "Ledger Compare Error: "
|
|
outputDirDesc = "Snapshot comparison json results output directory. Default is the current directory."
|
|
firstDiffsDesc = "Maximum number of differences to record in " + compare.FirstDiffsByHeight +
|
|
". Requesting a report with many differences may result in a large amount of memory usage. Defaults " +
|
|
" to 10. If set to 0, will not produce " + compare.FirstDiffsByHeight + "."
|
|
identifytxsErrorMessage = "Ledger Identify Transactions Error: "
|
|
snapshotDiffsPathDesc = "Path to json file containing list of target records to search for in transactions. This is typically output " +
|
|
"from ledgerutil compare."
|
|
blockStorePathDesc = "Path to file system of target peer, used to access block store. Defaults to '/var/hyperledger/production'. " +
|
|
"IMPORTANT: If the configuration for target peer's file system path was changed, the new path MUST be provided."
|
|
blockStorePathDefault = "/var/hyperledger/production"
|
|
outputDirIdDesc = "Location for identified transactions json results output directory. Default is the current directory."
|
|
verifyErrorMessage = "Verify Ledger Error:"
|
|
outputDirVerifyDesc = "Location for verification result output directory. Default is the current directory."
|
|
)
|
|
|
|
var (
|
|
app = kingpin.New("ledgerutil", "Ledger Utility Tool")
|
|
|
|
compareApp = app.Command("compare", "Compare channel snapshots from two different peers.")
|
|
snapshotPath1 = compareApp.Arg("snapshotPath1", "First ledger snapshot directory.").Required().String()
|
|
snapshotPath2 = compareApp.Arg("snapshotPath2", "Second ledger snapshot directory.").Required().String()
|
|
outputDir = compareApp.Flag("outputDir", outputDirDesc).Short('o').String()
|
|
firstDiffs = compareApp.Flag("firstDiffs", firstDiffsDesc).Short('f').Default("10").Int()
|
|
|
|
identifytxsApp = app.Command("identifytxs", "Identify potentially divergent transactions.")
|
|
snapshotDiffsPath = identifytxsApp.Arg("snapshotDiffsPath", snapshotDiffsPathDesc).Required().String()
|
|
blockStorePath = identifytxsApp.Arg("blockStorePath", blockStorePathDesc).Default(blockStorePathDefault).String()
|
|
outputDirId = identifytxsApp.Flag("outputDir", outputDirIdDesc).Short('o').String()
|
|
|
|
verifyApp = app.Command("verify", "Verify the integrity of a ledger")
|
|
blockStorePathVerify = verifyApp.Arg("blockStorePath", blockStorePathDesc).Default(blockStorePathDefault).String()
|
|
outputDirVerify = verifyApp.Flag("outputDir", outputDirVerifyDesc).Short('o').String()
|
|
|
|
args = os.Args[1:]
|
|
)
|
|
|
|
func main() {
|
|
kingpin.Version("0.0.1")
|
|
|
|
command, err := app.Parse(args)
|
|
if err != nil {
|
|
kingpin.Fatalf("parsing arguments: %s. Try --help", err)
|
|
return
|
|
}
|
|
|
|
// Command logic
|
|
switch command {
|
|
case compareApp.FullCommand():
|
|
|
|
// Determine result json file location
|
|
if *outputDir == "" {
|
|
*outputDir, err = os.Getwd()
|
|
if err != nil {
|
|
fmt.Printf("%s%s\n", compareErrorMessage, err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
count, outputDirPath, err := compare.Compare(*snapshotPath1, *snapshotPath2, *outputDir, *firstDiffs)
|
|
if err != nil {
|
|
fmt.Printf("%s%s\n", compareErrorMessage, err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
fmt.Print("\nSuccessfully compared snapshots. ")
|
|
if count == -1 {
|
|
fmt.Println("Both snapshot public state and private state hashes were the same. No results were generated.")
|
|
} else {
|
|
fmt.Printf("Results saved to %s. Total differences found: %d\n", outputDirPath, count)
|
|
os.Exit(2)
|
|
}
|
|
|
|
case identifytxsApp.FullCommand():
|
|
|
|
// Determine result json file location
|
|
if *outputDirId == "" {
|
|
*outputDirId, err = os.Getwd()
|
|
if err != nil {
|
|
fmt.Printf("%s%s\n", identifytxsErrorMessage, err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
firstBlock, lastBlock, err := identifytxs.IdentifyTxs(*snapshotDiffsPath, *blockStorePath, *outputDirId)
|
|
if err != nil {
|
|
fmt.Printf("%s%s\n", identifytxsErrorMessage, err)
|
|
os.Exit(1)
|
|
}
|
|
if firstBlock > lastBlock {
|
|
fmt.Printf("%sFirst available block was greater than highest record. No transactions were checked.", identifytxsErrorMessage)
|
|
os.Exit(1)
|
|
}
|
|
fmt.Printf("\nSuccessfully ran identify transactions tool. Transactions were checked between blocks %d and %d.", firstBlock, lastBlock)
|
|
|
|
case verifyApp.FullCommand():
|
|
|
|
// Determine result json file location
|
|
if *outputDirVerify == "" {
|
|
*outputDirVerify, err = os.Getwd()
|
|
if err != nil {
|
|
fmt.Printf("%s%s\n", verifyErrorMessage, err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
valid, err := verify.VerifyLedger(*blockStorePathVerify, *outputDirVerify)
|
|
if err != nil {
|
|
fmt.Printf("%s%s\n", verifyErrorMessage, err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
if valid {
|
|
fmt.Printf("\nSuccessfully executed verify tool. No error is found.\n")
|
|
} else {
|
|
fmt.Printf("\nSuccessfully executed verify tool. Some error(s) are found.\n")
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
}
|