2022-03-03 20:11:40 +00:00
|
|
|
package cmd
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"log"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"sort"
|
|
|
|
"strconv"
|
|
|
|
|
|
|
|
"github.com/ethereum/go-ethereum/cmd/utils"
|
2022-03-03 21:05:33 +00:00
|
|
|
"github.com/google/uuid"
|
2022-03-03 20:11:40 +00:00
|
|
|
"gopkg.in/urfave/cli.v1"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2022-03-05 19:49:53 +00:00
|
|
|
BlockchainFlag = cli.StringFlag{
|
|
|
|
Name: "blockchain",
|
|
|
|
Usage: `Which blockchain to crawl ("ethereum", "polygon")`,
|
|
|
|
}
|
2022-03-03 20:11:40 +00:00
|
|
|
DataDirFlag = cli.StringFlag{
|
|
|
|
Name: "datadir",
|
|
|
|
Usage: "Data directory for the databases and keystore",
|
|
|
|
Value: "/home/ubuntu/nodes/ethereum",
|
|
|
|
}
|
|
|
|
GCModeFlag = cli.StringFlag{
|
|
|
|
Name: "gcmode",
|
|
|
|
Usage: `Blockchain garbage collection mode ("full", "archive")`,
|
|
|
|
Value: "full",
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
// Parse start and end blocks from command line input
|
2022-03-05 19:49:53 +00:00
|
|
|
// TODO(kompotkot): Re-write to work via channel in goroutines
|
2022-03-03 20:11:40 +00:00
|
|
|
func startEndBlock(ctx *cli.Context) (uint64, uint64, error) {
|
|
|
|
start, err := strconv.ParseUint(ctx.Args().Get(0), 10, 32)
|
|
|
|
if err != nil {
|
|
|
|
return 0, 0, err
|
|
|
|
}
|
|
|
|
end, err := strconv.ParseUint(ctx.Args().Get(1), 10, 32)
|
|
|
|
if err != nil {
|
|
|
|
return 0, 0, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return start, end, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func processAddCommand(ctx *cli.Context) error {
|
|
|
|
if ctx.NArg() != 2 {
|
|
|
|
return fmt.Errorf("Required arguments: %v", ctx.Command.ArgsUsage)
|
|
|
|
}
|
2022-03-05 19:49:53 +00:00
|
|
|
blockchain := ctx.GlobalString(BlockchainFlag.Name)
|
|
|
|
if blockchain != "ethereum" && blockchain != "polygon" {
|
|
|
|
return fmt.Errorf("Unsupported blockchain provided")
|
|
|
|
}
|
2022-03-03 20:11:40 +00:00
|
|
|
|
|
|
|
start, end, err := startEndBlock(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Unable to parse block range: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = setLocalChain(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Unable to set blockchain: %v", err)
|
|
|
|
}
|
|
|
|
defer localConnections.Stack.Close()
|
|
|
|
defer localConnections.ChainDB.Close()
|
|
|
|
|
2022-03-05 19:49:53 +00:00
|
|
|
err = setDatabase()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Unable to set database connection: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = add(blockchain, start, end)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Error occurred due add acction: %v", err)
|
|
|
|
}
|
2022-03-03 20:11:40 +00:00
|
|
|
|
|
|
|
localConnections.Chain.Stop()
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func processShowCommand(ctx *cli.Context) error {
|
|
|
|
if ctx.NArg() != 2 {
|
|
|
|
return fmt.Errorf("Required arguments: %v", ctx.Command.ArgsUsage)
|
|
|
|
}
|
2022-03-05 19:49:53 +00:00
|
|
|
blockchain := ctx.GlobalString(BlockchainFlag.Name)
|
|
|
|
if blockchain != "ethereum" && blockchain != "polygon" {
|
|
|
|
return fmt.Errorf("Unsupported blockchain provided")
|
|
|
|
}
|
2022-03-03 20:11:40 +00:00
|
|
|
|
|
|
|
start, end, err := startEndBlock(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Unable to parse block range: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = setLocalChain(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Unable to set blockchain: %v", err)
|
|
|
|
}
|
|
|
|
defer localConnections.Stack.Close()
|
|
|
|
defer localConnections.ChainDB.Close()
|
|
|
|
|
2022-03-05 19:49:53 +00:00
|
|
|
err = show(start, end)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Error occurred due show acction: %v", err)
|
|
|
|
}
|
2022-03-03 20:11:40 +00:00
|
|
|
|
|
|
|
localConnections.Chain.Stop()
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func processVerifyCommand(ctx *cli.Context) error {
|
|
|
|
if ctx.NArg() != 2 {
|
|
|
|
return fmt.Errorf("Required arguments: %v", ctx.Command.ArgsUsage)
|
|
|
|
}
|
2022-03-05 19:49:53 +00:00
|
|
|
blockchain := ctx.GlobalString(BlockchainFlag.Name)
|
|
|
|
if blockchain != "ethereum" && blockchain != "polygon" {
|
|
|
|
return fmt.Errorf("Unsupported blockchain provided")
|
|
|
|
}
|
2022-03-03 20:11:40 +00:00
|
|
|
|
|
|
|
start, end, err := startEndBlock(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Unable to parse block range: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = setLocalChain(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Unable to set blockchain: %v", err)
|
|
|
|
}
|
|
|
|
defer localConnections.Stack.Close()
|
|
|
|
defer localConnections.ChainDB.Close()
|
|
|
|
|
|
|
|
err = setDatabase()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Unable to set database connection: %v", err)
|
|
|
|
}
|
|
|
|
|
2022-03-05 19:49:53 +00:00
|
|
|
err = verify(blockchain, start, end)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Error occurred due verify acction: %v", err)
|
|
|
|
}
|
2022-03-03 20:11:40 +00:00
|
|
|
|
|
|
|
localConnections.Chain.Stop()
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func LDBCLI() {
|
|
|
|
app := cli.NewApp()
|
|
|
|
app.Name = filepath.Base(os.Args[0])
|
|
|
|
app.Author = "Bugout.dev"
|
|
|
|
app.Email = "engineering@bugout.dev"
|
|
|
|
app.Usage = "blockchain ldb extractor command line interface"
|
|
|
|
app.Flags = []cli.Flag{
|
2022-03-05 19:49:53 +00:00
|
|
|
BlockchainFlag,
|
2022-03-03 20:11:40 +00:00
|
|
|
DataDirFlag,
|
|
|
|
GCModeFlag,
|
|
|
|
}
|
2022-03-05 19:49:53 +00:00
|
|
|
|
2022-03-03 20:11:40 +00:00
|
|
|
app.Commands = []cli.Command{
|
|
|
|
{
|
|
|
|
Name: "add",
|
|
|
|
Action: utils.MigrateFlags(processAddCommand),
|
|
|
|
ArgsUsage: "<start_block> <end_block>",
|
|
|
|
Usage: "Add new blocks with transactions to database",
|
|
|
|
Description: "This command request blocks from blockchain and adds to database.",
|
|
|
|
Flags: []cli.Flag{
|
2022-03-05 19:49:53 +00:00
|
|
|
BlockchainFlag,
|
2022-03-03 20:11:40 +00:00
|
|
|
DataDirFlag,
|
|
|
|
GCModeFlag,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "show",
|
|
|
|
Action: utils.MigrateFlags(processShowCommand),
|
|
|
|
ArgsUsage: "<start_block> <end_block>",
|
|
|
|
Usage: "Show block with transactions",
|
|
|
|
Description: "This command print out requested blocks.",
|
|
|
|
Flags: []cli.Flag{
|
2022-03-05 19:49:53 +00:00
|
|
|
BlockchainFlag,
|
2022-03-03 20:11:40 +00:00
|
|
|
DataDirFlag,
|
|
|
|
GCModeFlag,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "verify",
|
|
|
|
Action: utils.MigrateFlags(processVerifyCommand),
|
|
|
|
ArgsUsage: "<start_block> <end_block>",
|
|
|
|
Usage: "Verify blocks with transactions at database",
|
|
|
|
Description: "This command compare blocks in database and in blockchain for difference.",
|
|
|
|
Flags: []cli.Flag{
|
2022-03-05 19:49:53 +00:00
|
|
|
BlockchainFlag,
|
2022-03-03 20:11:40 +00:00
|
|
|
DataDirFlag,
|
|
|
|
GCModeFlag,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
sort.Sort(cli.FlagsByName(app.Flags))
|
|
|
|
sort.Sort(cli.CommandsByName(app.Commands))
|
|
|
|
|
2022-03-05 19:13:42 +00:00
|
|
|
// Initialize local connections
|
2022-03-03 20:11:40 +00:00
|
|
|
localConnections = &LocalConnections{}
|
2022-03-03 21:05:33 +00:00
|
|
|
|
2022-03-05 19:13:42 +00:00
|
|
|
// Initialize humbug client to be able write data in Bugout journal
|
|
|
|
humbugReporter = &HumbugReporter{}
|
2022-03-03 21:05:33 +00:00
|
|
|
sessionID := uuid.New().String()
|
|
|
|
err := setHumbugClient(sessionID)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
2022-03-03 20:11:40 +00:00
|
|
|
|
2022-03-03 21:05:33 +00:00
|
|
|
err = app.Run(os.Args)
|
2022-03-03 20:11:40 +00:00
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|