diff --git a/client/commands/proofs/get.go b/client/commands/proofs/get.go index 645aba47d..b200c92c6 100644 --- a/client/commands/proofs/get.go +++ b/client/commands/proofs/get.go @@ -18,13 +18,12 @@ import ( "github.com/tendermint/basecoin/client/commands" ) -// Get does most of the work of the query commands, but is quite -// opinionated, so if you want more control, set up the items and call Get -// directly. Notably, it always uses go-wire.ReadBinaryBytes to deserialize, -// and Height and Node from standard flags. +// GetParsed does most of the work of the query commands, but is quite +// opinionated, so if you want more control about parsing, call Get +// directly. // // It will try to get the proof for the given key. If it is successful, -// it will return the proof and also unserialize proof.Data into the data +// it will return the height and also unserialize proof.Data into the data // argument (so pass in a pointer to the appropriate struct) func GetParsed(key []byte, data interface{}, prove bool) (uint64, error) { bs, h, err := Get(key, prove) @@ -38,6 +37,14 @@ func GetParsed(key []byte, data interface{}, prove bool) (uint64, error) { return h, nil } +// Get queries the given key and returns the value stored there and the +// height we checked at. +// +// If prove is true (and why shouldn't it be?), +// the data is fully verified before returning. If prove is false, +// we just repeat whatever any (potentially malicious) node gives us. +// Only use that if you are running the full node yourself, +// and it is localhost or you have a secure connection (not HTTP) func Get(key []byte, prove bool) (data.Bytes, uint64, error) { if !prove { node := commands.GetNode() @@ -48,6 +55,9 @@ func Get(key []byte, prove bool) (data.Bytes, uint64, error) { return val, h, err } +// GetWithProof returns the values stored under a given key at the named +// height as in Get. Additionally, it will return a validated merkle +// proof for the key-value pair if it exists, and all checks pass. func GetWithProof(key []byte) (data.Bytes, uint64, *iavl.KeyExistsProof, error) { node := commands.GetNode() @@ -92,14 +102,14 @@ func GetWithProof(key []byte) (data.Bytes, uint64, *iavl.KeyExistsProof, error) // GetCertifiedCheckpoint gets the signed header for a given height // and certifies it. Returns error if unable to get a proven header. func GetCertifiedCheckpoint(h int) (empty lc.Checkpoint, err error) { - // here is the certifier, root of all knowledge + // here is the certifier, root of all trust node := commands.GetNode() cert, err := commands.GetCertifier() if err != nil { return } - // get and validate a signed header for this proof + // get the checkpoint for this height // FIXME: cannot use cert.GetByHeight for now, as it also requires // Validators and will fail on querying tendermint for non-current height. @@ -113,12 +123,11 @@ func GetCertifiedCheckpoint(h int) (empty lc.Checkpoint, err error) { Header: commit.Header, Commit: commit.Commit, } - // double check we got the same height + + // validate downloaded checkpoint with our request and trust store. if check.Height() != h { return empty, lc.ErrHeightMismatch(h, check.Height()) } - - // and now verify it matches our validators err = cert.Certify(check) return check, nil } @@ -140,6 +149,7 @@ func ParseHexKey(args []string, argname string) ([]byte, error) { return proofs.ParseHexKey(rawkey) } +// GetHeight reads the viper config for the query height func GetHeight() int { return viper.GetInt(FlagHeight) } diff --git a/client/commands/proofs/tx.go b/client/commands/proofs/tx.go index c5a80c1fa..1aa0e11f9 100644 --- a/client/commands/proofs/tx.go +++ b/client/commands/proofs/tx.go @@ -4,15 +4,13 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - "github.com/tendermint/light-client/proofs" + "github.com/tendermint/basecoin" + wire "github.com/tendermint/go-wire" "github.com/tendermint/tendermint/types" "github.com/tendermint/basecoin/client/commands" ) -//nolint TODO add description -var TxPresenters = proofs.NewPresenters() - // TxQueryCmd - CLI command to query a transaction with proof var TxQueryCmd = &cobra.Command{ Use: "tx [txhash]", @@ -26,21 +24,6 @@ data to other peers as needed. RunE: commands.RequireInit(txQueryCmd), } -// type ResultTx struct { -// Height int `json:"height"` -// Index int `json:"index"` -// TxResult abci.Result `json:"tx_result"` -// Tx types.Tx `json:"tx"` -// Proof types.TxProof `json:"proof,omitempty"` -// } - -// type TxProof struct { -// Index, Total int -// RootHash data.Bytes -// Data Tx -// Proof merkle.SimpleProof -// } - func txQueryCmd(cmd *cobra.Command, args []string) error { // parse cli // TODO: when querying historical heights is allowed... pass it @@ -58,6 +41,7 @@ func txQueryCmd(cmd *cobra.Command, args []string) error { return err } + // no checks if we don't get a proof if !prove { return showTx(res.Height, res.Tx) } @@ -71,17 +55,17 @@ func txQueryCmd(cmd *cobra.Command, args []string) error { return err } + // note that we return res.Proof.Data, not res.Tx, + // as res.Proof.Validate only verifies res.Proof.Data return showTx(res.Height, res.Proof.Data) } +// showTx parses anything that was previously registered as basecoin.Tx func showTx(h int, tx types.Tx) error { - // auto-determine which tx it was, over all registered tx types - info, err := TxPresenters.BruteForce(tx) + var info basecoin.Tx + err := wire.ReadBinaryBytes(tx, &info) if err != nil { return err } - - // we can reuse this output for other commands for text/json - // unless they do something special like store a file to disk return OutputProof(info, uint64(h)) } diff --git a/client/commands/txs/presenter.go b/client/commands/txs/presenter.go deleted file mode 100644 index 2886e7bd2..000000000 --- a/client/commands/txs/presenter.go +++ /dev/null @@ -1,20 +0,0 @@ -package txs - -import ( - wire "github.com/tendermint/go-wire" - "github.com/tendermint/light-client/proofs" - - "github.com/tendermint/basecoin" -) - -// BaseTxPresenter this decodes all basecoin tx -type BaseTxPresenter struct { - proofs.RawPresenter // this handles MakeKey as hex bytes -} - -// ParseData - unmarshal raw bytes to a basecoin tx -func (BaseTxPresenter) ParseData(raw []byte) (interface{}, error) { - var tx basecoin.Tx - err := wire.ReadBinaryBytes(raw, &tx) - return tx, err -} diff --git a/cmd/basecli/main.go b/cmd/basecli/main.go index 6813dd916..06aaedf38 100644 --- a/cmd/basecli/main.go +++ b/cmd/basecli/main.go @@ -49,7 +49,6 @@ func main() { rolecmd.RoleQueryCmd, ibccmd.IBCQueryCmd, ) - proofs.TxPresenters.Register("base", txcmd.BaseTxPresenter{}) // set up the middleware txcmd.Middleware = txcmd.Wrappers{ diff --git a/docs/guide/counter/cmd/countercli/main.go b/docs/guide/counter/cmd/countercli/main.go index 6e930cd7d..5d7f1df38 100644 --- a/docs/guide/counter/cmd/countercli/main.go +++ b/docs/guide/counter/cmd/countercli/main.go @@ -58,7 +58,6 @@ func main() { txcmd.Middleware.Register(txcmd.RootCmd.PersistentFlags()) // Prepare transactions - proofs.TxPresenters.Register("base", txcmd.BaseTxPresenter{}) txcmd.RootCmd.AddCommand( // This is the default transaction, optional in your app coincmd.SendTxCmd,