mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-12-12 05:42:25 +01:00
cmd: add chain subcommand
Chain subcommand includes the commands: getblock, getbestblock, and getblockhash. This commit removes conflicting neutrino cli commands.
This commit is contained in:
219
cmd/lncli/chainrpc_active.go
Normal file
219
cmd/lncli/chainrpc_active.go
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
//go:build chainrpc
|
||||||
|
// +build chainrpc
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
|
"github.com/btcsuite/btcd/wire"
|
||||||
|
"github.com/lightningnetwork/lnd/lnrpc/chainrpc"
|
||||||
|
"github.com/urfave/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
// chainCommands will return the set of commands to enable for chainrpc builds.
|
||||||
|
func chainCommands() []cli.Command {
|
||||||
|
return []cli.Command{
|
||||||
|
{
|
||||||
|
Name: "chain",
|
||||||
|
Category: "On-chain",
|
||||||
|
Usage: "Interact with the bitcoin blockchain.",
|
||||||
|
Subcommands: []cli.Command{
|
||||||
|
getBlockCommand,
|
||||||
|
getBestBlockCommand,
|
||||||
|
getBlockHashCommand,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getChainClient(ctx *cli.Context) (chainrpc.ChainKitClient, func()) {
|
||||||
|
conn := getClientConn(ctx, false)
|
||||||
|
|
||||||
|
cleanUp := func() {
|
||||||
|
conn.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
return chainrpc.NewChainKitClient(conn), cleanUp
|
||||||
|
}
|
||||||
|
|
||||||
|
var getBlockCommand = cli.Command{
|
||||||
|
Name: "getblock",
|
||||||
|
Category: "On-chain",
|
||||||
|
Usage: "Get block by block hash.",
|
||||||
|
Description: "Returns a block given the corresponding block hash.",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "hash",
|
||||||
|
Usage: "the target block hash",
|
||||||
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "verbose",
|
||||||
|
Usage: "print entire block as JSON",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: actionDecorator(getBlock),
|
||||||
|
}
|
||||||
|
|
||||||
|
func getBlock(ctx *cli.Context) error {
|
||||||
|
ctxc := getContext()
|
||||||
|
|
||||||
|
var (
|
||||||
|
args = ctx.Args()
|
||||||
|
blockHashString string
|
||||||
|
)
|
||||||
|
|
||||||
|
verbose := false
|
||||||
|
if ctx.IsSet("verbose") {
|
||||||
|
verbose = true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case ctx.IsSet("hash"):
|
||||||
|
blockHashString = ctx.String("hash")
|
||||||
|
|
||||||
|
case args.Present():
|
||||||
|
blockHashString = args.First()
|
||||||
|
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("hash argument missing")
|
||||||
|
}
|
||||||
|
|
||||||
|
blockHash, err := chainhash.NewHashFromStr(blockHashString)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client, cleanUp := getChainClient(ctx)
|
||||||
|
defer cleanUp()
|
||||||
|
|
||||||
|
req := &chainrpc.GetBlockRequest{BlockHash: blockHash.CloneBytes()}
|
||||||
|
resp, err := client.GetBlock(ctxc, req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert raw block bytes into wire.MsgBlock.
|
||||||
|
msgBlock := &wire.MsgBlock{}
|
||||||
|
blockReader := bytes.NewReader(resp.RawBlock)
|
||||||
|
err = msgBlock.Deserialize(blockReader)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if verbose {
|
||||||
|
printJSON(msgBlock)
|
||||||
|
} else {
|
||||||
|
printJSON(msgBlock.Header)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var getBestBlockCommand = cli.Command{
|
||||||
|
Name: "getbestblock",
|
||||||
|
Category: "On-chain",
|
||||||
|
Usage: "Get best block.",
|
||||||
|
Description: "Returns the latest block hash and height from the " +
|
||||||
|
"valid most-work chain.",
|
||||||
|
Action: actionDecorator(getBestBlock),
|
||||||
|
}
|
||||||
|
|
||||||
|
func getBestBlock(ctx *cli.Context) error {
|
||||||
|
ctxc := getContext()
|
||||||
|
|
||||||
|
client, cleanUp := getChainClient(ctx)
|
||||||
|
defer cleanUp()
|
||||||
|
|
||||||
|
resp, err := client.GetBestBlock(ctxc, &chainrpc.GetBestBlockRequest{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cast gRPC block hash bytes as chain hash type.
|
||||||
|
var blockHash chainhash.Hash
|
||||||
|
copy(blockHash[:], resp.BlockHash)
|
||||||
|
|
||||||
|
printJSON(struct {
|
||||||
|
BlockHash chainhash.Hash `json:"block_hash"`
|
||||||
|
BlockHeight int32 `json:"block_height"`
|
||||||
|
}{
|
||||||
|
BlockHash: blockHash,
|
||||||
|
BlockHeight: resp.BlockHeight,
|
||||||
|
})
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var getBlockHashCommand = cli.Command{
|
||||||
|
Name: "getblockhash",
|
||||||
|
Category: "On-chain",
|
||||||
|
Usage: "Get block hash by block height.",
|
||||||
|
Description: "Returns the block hash from the best chain at a given " +
|
||||||
|
"height.",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.Int64Flag{
|
||||||
|
Name: "height",
|
||||||
|
Usage: "target block height",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: actionDecorator(getBlockHash),
|
||||||
|
}
|
||||||
|
|
||||||
|
func getBlockHash(ctx *cli.Context) error {
|
||||||
|
ctxc := getContext()
|
||||||
|
|
||||||
|
// Display the command's help message if we do not have the expected
|
||||||
|
// number of arguments/flags.
|
||||||
|
if ctx.NArg()+ctx.NumFlags() != 1 {
|
||||||
|
return cli.ShowCommandHelp(ctx, "getblockhash")
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
args = ctx.Args()
|
||||||
|
blockHeight int64
|
||||||
|
)
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case ctx.IsSet("height"):
|
||||||
|
blockHeight = ctx.Int64("height")
|
||||||
|
|
||||||
|
case args.Present():
|
||||||
|
blockHeightString := args.First()
|
||||||
|
|
||||||
|
// Convert block height positional argument from string to
|
||||||
|
// int64.
|
||||||
|
var err error
|
||||||
|
blockHeight, err = strconv.ParseInt(blockHeightString, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("block height argument missing")
|
||||||
|
}
|
||||||
|
|
||||||
|
client, cleanUp := getChainClient(ctx)
|
||||||
|
defer cleanUp()
|
||||||
|
|
||||||
|
req := &chainrpc.GetBlockHashRequest{BlockHeight: blockHeight}
|
||||||
|
resp, err := client.GetBlockHash(ctxc, req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cast gRPC block hash bytes as chain hash type.
|
||||||
|
var blockHash chainhash.Hash
|
||||||
|
copy(blockHash[:], resp.BlockHash)
|
||||||
|
|
||||||
|
printJSON(struct {
|
||||||
|
BlockHash chainhash.Hash `json:"block_hash"`
|
||||||
|
}{
|
||||||
|
BlockHash: blockHash,
|
||||||
|
})
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
11
cmd/lncli/chainrpc_default.go
Normal file
11
cmd/lncli/chainrpc_default.go
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
//go:build !chainrpc
|
||||||
|
// +build !chainrpc
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "github.com/urfave/cli"
|
||||||
|
|
||||||
|
// chainCommands will return nil for non-chainrpc builds.
|
||||||
|
func chainCommands() []cli.Command {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -500,6 +500,7 @@ func main() {
|
|||||||
app.Commands = append(app.Commands, wtclientCommands()...)
|
app.Commands = append(app.Commands, wtclientCommands()...)
|
||||||
app.Commands = append(app.Commands, devCommands()...)
|
app.Commands = append(app.Commands, devCommands()...)
|
||||||
app.Commands = append(app.Commands, peersCommands()...)
|
app.Commands = append(app.Commands, peersCommands()...)
|
||||||
|
app.Commands = append(app.Commands, chainCommands()...)
|
||||||
|
|
||||||
if err := app.Run(os.Args); err != nil {
|
if err := app.Run(os.Args); err != nil {
|
||||||
fatal(err)
|
fatal(err)
|
||||||
|
|||||||
@@ -4,8 +4,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/lightningnetwork/lnd/lnrpc/neutrinorpc"
|
"github.com/lightningnetwork/lnd/lnrpc/neutrinorpc"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
@@ -193,42 +191,6 @@ func getBlockHeader(ctx *cli.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var getBlockCommand = cli.Command{
|
|
||||||
Name: "getblock",
|
|
||||||
Usage: "Get a block.",
|
|
||||||
Category: "Neutrino",
|
|
||||||
Description: "Returns a block with a particular block hash.",
|
|
||||||
ArgsUsage: "hash",
|
|
||||||
Action: actionDecorator(getBlock),
|
|
||||||
}
|
|
||||||
|
|
||||||
func getBlock(ctx *cli.Context) error {
|
|
||||||
ctxc := getContext()
|
|
||||||
args := ctx.Args()
|
|
||||||
|
|
||||||
// Display the command's help message if we do not have the expected
|
|
||||||
// number of arguments/flags.
|
|
||||||
if !args.Present() {
|
|
||||||
return cli.ShowCommandHelp(ctx, "getblock")
|
|
||||||
}
|
|
||||||
|
|
||||||
client, cleanUp := getNeutrinoKitClient(ctx)
|
|
||||||
defer cleanUp()
|
|
||||||
|
|
||||||
req := &neutrinorpc.GetBlockRequest{
|
|
||||||
Hash: args.First(),
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := client.GetBlock(ctxc, req)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
printRespJSON(resp)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var getCFilterCommand = cli.Command{
|
var getCFilterCommand = cli.Command{
|
||||||
Name: "getcfilter",
|
Name: "getcfilter",
|
||||||
Usage: "Get a compact filter.",
|
Usage: "Get a compact filter.",
|
||||||
@@ -263,47 +225,6 @@ func getCFilter(ctx *cli.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var getBlockHashCommand = cli.Command{
|
|
||||||
Name: "getblockhash",
|
|
||||||
Usage: "Get a block hash.",
|
|
||||||
Category: "Neutrino",
|
|
||||||
Description: "Returns the header hash of a block at a given height.",
|
|
||||||
ArgsUsage: "height",
|
|
||||||
Action: actionDecorator(getBlockHash),
|
|
||||||
}
|
|
||||||
|
|
||||||
func getBlockHash(ctx *cli.Context) error {
|
|
||||||
ctxc := getContext()
|
|
||||||
args := ctx.Args()
|
|
||||||
|
|
||||||
// Display the command's help message if we do not have the expected
|
|
||||||
// number of arguments/flags.
|
|
||||||
if !args.Present() {
|
|
||||||
return cli.ShowCommandHelp(ctx, "getblockhash")
|
|
||||||
}
|
|
||||||
|
|
||||||
client, cleanUp := getNeutrinoKitClient(ctx)
|
|
||||||
defer cleanUp()
|
|
||||||
|
|
||||||
height, err := strconv.ParseInt(args.First(), 10, 32)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
req := &neutrinorpc.GetBlockHashRequest{
|
|
||||||
Height: int32(height),
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := client.GetBlockHash(ctxc, req)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
printRespJSON(resp)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// neutrinoCommands will return the set of commands to enable for neutrinorpc
|
// neutrinoCommands will return the set of commands to enable for neutrinorpc
|
||||||
// builds.
|
// builds.
|
||||||
func neutrinoCommands() []cli.Command {
|
func neutrinoCommands() []cli.Command {
|
||||||
@@ -318,10 +239,8 @@ func neutrinoCommands() []cli.Command {
|
|||||||
addPeerCommand,
|
addPeerCommand,
|
||||||
disconnectPeerCommand,
|
disconnectPeerCommand,
|
||||||
isBannedCommand,
|
isBannedCommand,
|
||||||
getBlockCommand,
|
|
||||||
getBlockHeaderCommand,
|
getBlockHeaderCommand,
|
||||||
getCFilterCommand,
|
getCFilterCommand,
|
||||||
getBlockHashCommand,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -7,7 +7,7 @@ require (
|
|||||||
github.com/btcsuite/btcd/btcec/v2 v2.2.2
|
github.com/btcsuite/btcd/btcec/v2 v2.2.2
|
||||||
github.com/btcsuite/btcd/btcutil v1.1.3
|
github.com/btcsuite/btcd/btcutil v1.1.3
|
||||||
github.com/btcsuite/btcd/btcutil/psbt v1.1.5
|
github.com/btcsuite/btcd/btcutil/psbt v1.1.5
|
||||||
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1
|
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2
|
||||||
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f
|
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f
|
||||||
github.com/btcsuite/btcwallet v0.16.6-0.20221203002441-6c7480c8a46b
|
github.com/btcsuite/btcwallet v0.16.6-0.20221203002441-6c7480c8a46b
|
||||||
github.com/btcsuite/btcwallet/wallet/txauthor v1.3.2
|
github.com/btcsuite/btcwallet/wallet/txauthor v1.3.2
|
||||||
|
|||||||
2
go.sum
2
go.sum
@@ -96,6 +96,8 @@ github.com/btcsuite/btcd/btcutil/psbt v1.1.5/go.mod h1:kA6FLH/JfUx++j9pYU0pyu+Z8
|
|||||||
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
|
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
|
||||||
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U=
|
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U=
|
||||||
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
|
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
|
||||||
|
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2 h1:KdUfX2zKommPRa+PD0sWZUyXe9w277ABlgELO7H04IM=
|
||||||
|
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
|
||||||
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo=
|
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo=
|
||||||
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
|
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
|
||||||
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
|
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
|
||||||
|
|||||||
Reference in New Issue
Block a user