Merge pull request #177 from tendermint/feature/104-autoseq
Auto Sequencing, Error Cleanup, Bash Tests Cleanup
This commit is contained in:
commit
29273e5656
|
@ -7,10 +7,12 @@ import (
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/tendermint/basecoin/modules/coin"
|
|
||||||
eyescli "github.com/tendermint/merkleeyes/client"
|
eyescli "github.com/tendermint/merkleeyes/client"
|
||||||
cmn "github.com/tendermint/tmlibs/common"
|
cmn "github.com/tendermint/tmlibs/common"
|
||||||
"github.com/tendermint/tmlibs/log"
|
"github.com/tendermint/tmlibs/log"
|
||||||
|
|
||||||
|
"github.com/tendermint/basecoin/modules/coin"
|
||||||
)
|
)
|
||||||
|
|
||||||
const genesisFilepath = "./testdata/genesis.json"
|
const genesisFilepath = "./testdata/genesis.json"
|
||||||
|
|
|
@ -15,19 +15,19 @@ import (
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
|
"github.com/tendermint/light-client/certifiers"
|
||||||
|
"github.com/tendermint/light-client/certifiers/files"
|
||||||
"github.com/tendermint/tmlibs/cli"
|
"github.com/tendermint/tmlibs/cli"
|
||||||
cmn "github.com/tendermint/tmlibs/common"
|
cmn "github.com/tendermint/tmlibs/common"
|
||||||
|
|
||||||
"github.com/tendermint/tendermint/types"
|
"github.com/tendermint/tendermint/types"
|
||||||
|
|
||||||
"github.com/tendermint/light-client/certifiers"
|
|
||||||
"github.com/tendermint/light-client/certifiers/files"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
dirPerm = os.FileMode(0700)
|
dirPerm = os.FileMode(0700)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//nolint
|
||||||
const (
|
const (
|
||||||
SeedFlag = "seed"
|
SeedFlag = "seed"
|
||||||
HashFlag = "valhash"
|
HashFlag = "valhash"
|
||||||
|
|
|
@ -8,12 +8,11 @@ import (
|
||||||
|
|
||||||
wire "github.com/tendermint/go-wire"
|
wire "github.com/tendermint/go-wire"
|
||||||
"github.com/tendermint/go-wire/data"
|
"github.com/tendermint/go-wire/data"
|
||||||
|
lc "github.com/tendermint/light-client"
|
||||||
|
"github.com/tendermint/light-client/proofs"
|
||||||
"github.com/tendermint/tendermint/rpc/client"
|
"github.com/tendermint/tendermint/rpc/client"
|
||||||
|
|
||||||
lc "github.com/tendermint/light-client"
|
|
||||||
"github.com/tendermint/basecoin/client/commands"
|
"github.com/tendermint/basecoin/client/commands"
|
||||||
"github.com/tendermint/light-client/proofs"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetAndParseAppProof does most of the work of the query commands, but is quite
|
// GetAndParseAppProof does most of the work of the query commands, but is quite
|
||||||
|
|
|
@ -4,24 +4,25 @@ import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/tendermint/go-wire/data"
|
"github.com/tendermint/go-wire/data"
|
||||||
|
"github.com/tendermint/light-client/proofs"
|
||||||
|
|
||||||
"github.com/tendermint/basecoin/client/commands"
|
"github.com/tendermint/basecoin/client/commands"
|
||||||
"github.com/tendermint/light-client/proofs"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var KeyCmd = &cobra.Command{
|
// KeyQueryCmd - CLI command to query a state by key with proof
|
||||||
|
var KeyQueryCmd = &cobra.Command{
|
||||||
Use: "key [key]",
|
Use: "key [key]",
|
||||||
Short: "Handle proofs for state of abci app",
|
Short: "Handle proofs for state of abci app",
|
||||||
Long: `This will look up a given key in the abci app, verify the proof,
|
Long: `This will look up a given key in the abci app, verify the proof,
|
||||||
and output it as hex.
|
and output it as hex.
|
||||||
|
|
||||||
If you want json output, use an app-specific command that knows key and value structure.`,
|
If you want json output, use an app-specific command that knows key and value structure.`,
|
||||||
RunE: commands.RequireInit(doKeyQuery),
|
RunE: commands.RequireInit(keyQueryCmd),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: we cannot yse GetAndParseAppProof here, as we don't use go-wire to
|
// Note: we cannot yse GetAndParseAppProof here, as we don't use go-wire to
|
||||||
// parse the object, but rather return the raw bytes
|
// parse the object, but rather return the raw bytes
|
||||||
func doKeyQuery(cmd *cobra.Command, args []string) error {
|
func keyQueryCmd(cmd *cobra.Command, args []string) error {
|
||||||
// parse cli
|
// parse cli
|
||||||
height := GetHeight()
|
height := GetHeight()
|
||||||
key, err := ParseHexKey(args, "key")
|
key, err := ParseHexKey(args, "key")
|
||||||
|
|
|
@ -3,13 +3,16 @@ package proofs
|
||||||
import (
|
import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/tendermint/basecoin/client/commands"
|
|
||||||
"github.com/tendermint/light-client/proofs"
|
"github.com/tendermint/light-client/proofs"
|
||||||
|
|
||||||
|
"github.com/tendermint/basecoin/client/commands"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//nolint TODO add description
|
||||||
var TxPresenters = proofs.NewPresenters()
|
var TxPresenters = proofs.NewPresenters()
|
||||||
|
|
||||||
var TxCmd = &cobra.Command{
|
// TxQueryCmd - CLI command to query a transaction with proof
|
||||||
|
var TxQueryCmd = &cobra.Command{
|
||||||
Use: "tx [txhash]",
|
Use: "tx [txhash]",
|
||||||
Short: "Handle proofs of commited txs",
|
Short: "Handle proofs of commited txs",
|
||||||
Long: `Proofs allows you to validate abci state with merkle proofs.
|
Long: `Proofs allows you to validate abci state with merkle proofs.
|
||||||
|
@ -18,10 +21,10 @@ These proofs tie the data to a checkpoint, which is managed by "seeds".
|
||||||
Here we can validate these proofs and import/export them to prove specific
|
Here we can validate these proofs and import/export them to prove specific
|
||||||
data to other peers as needed.
|
data to other peers as needed.
|
||||||
`,
|
`,
|
||||||
RunE: commands.RequireInit(doTxQuery),
|
RunE: commands.RequireInit(txQueryCmd),
|
||||||
}
|
}
|
||||||
|
|
||||||
func doTxQuery(cmd *cobra.Command, args []string) error {
|
func txQueryCmd(cmd *cobra.Command, args []string) error {
|
||||||
// parse cli
|
// parse cli
|
||||||
height := GetHeight()
|
height := GetHeight()
|
||||||
bkey, err := ParseHexKey(args, "txhash")
|
bkey, err := ParseHexKey(args, "txhash")
|
||||||
|
|
|
@ -7,14 +7,13 @@ import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
cmn "github.com/tendermint/tmlibs/common"
|
certclient "github.com/tendermint/light-client/certifiers/client"
|
||||||
"github.com/tendermint/tmlibs/log"
|
|
||||||
|
|
||||||
"github.com/tendermint/tendermint/rpc/client"
|
"github.com/tendermint/tendermint/rpc/client"
|
||||||
"github.com/tendermint/tendermint/rpc/core"
|
"github.com/tendermint/tendermint/rpc/core"
|
||||||
rpc "github.com/tendermint/tendermint/rpc/lib/server"
|
rpc "github.com/tendermint/tendermint/rpc/lib/server"
|
||||||
|
cmn "github.com/tendermint/tmlibs/common"
|
||||||
|
"github.com/tendermint/tmlibs/log"
|
||||||
|
|
||||||
certclient "github.com/tendermint/light-client/certifiers/client"
|
|
||||||
"github.com/tendermint/basecoin/client/commands"
|
"github.com/tendermint/basecoin/client/commands"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package rpc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/tendermint/basecoin/client/commands"
|
"github.com/tendermint/basecoin/client/commands"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,9 @@ import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/tendermint/go-wire/data"
|
"github.com/tendermint/go-wire/data"
|
||||||
|
certclient "github.com/tendermint/light-client/certifiers/client"
|
||||||
"github.com/tendermint/tendermint/rpc/client"
|
"github.com/tendermint/tendermint/rpc/client"
|
||||||
|
|
||||||
certclient "github.com/tendermint/light-client/certifiers/client"
|
|
||||||
"github.com/tendermint/basecoin/client/commands"
|
"github.com/tendermint/basecoin/client/commands"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package rpc
|
||||||
import (
|
import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
"github.com/tendermint/basecoin/client/commands"
|
"github.com/tendermint/basecoin/client/commands"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
"github.com/tendermint/basecoin/client/commands"
|
"github.com/tendermint/basecoin/client/commands"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,9 @@ import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
"github.com/tendermint/light-client/certifiers"
|
"github.com/tendermint/light-client/certifiers"
|
||||||
|
|
||||||
"github.com/tendermint/basecoin/client/commands"
|
"github.com/tendermint/basecoin/client/commands"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,9 @@ import (
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
"github.com/tendermint/light-client/certifiers"
|
"github.com/tendermint/light-client/certifiers"
|
||||||
|
|
||||||
"github.com/tendermint/basecoin/client/commands"
|
"github.com/tendermint/basecoin/client/commands"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,9 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/tendermint/light-client/certifiers"
|
"github.com/tendermint/light-client/certifiers"
|
||||||
|
|
||||||
"github.com/tendermint/basecoin/client/commands"
|
"github.com/tendermint/basecoin/client/commands"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package txs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
wire "github.com/tendermint/go-wire"
|
wire "github.com/tendermint/go-wire"
|
||||||
"github.com/tendermint/light-client/proofs"
|
"github.com/tendermint/light-client/proofs"
|
||||||
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
"github.com/tendermint/basecoin"
|
"github.com/tendermint/basecoin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -51,8 +51,8 @@ func main() {
|
||||||
// Prepare queries
|
// Prepare queries
|
||||||
proofs.RootCmd.AddCommand(
|
proofs.RootCmd.AddCommand(
|
||||||
// These are default parsers, but optional in your app (you can remove key)
|
// These are default parsers, but optional in your app (you can remove key)
|
||||||
proofs.TxCmd,
|
proofs.TxQueryCmd,
|
||||||
proofs.KeyCmd,
|
proofs.KeyQueryCmd,
|
||||||
coincmd.AccountQueryCmd,
|
coincmd.AccountQueryCmd,
|
||||||
noncecmd.NonceQueryCmd,
|
noncecmd.NonceQueryCmd,
|
||||||
)
|
)
|
||||||
|
|
|
@ -8,8 +8,6 @@ import (
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
//"github.com/pkg/errors"
|
|
||||||
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
"github.com/tendermint/go-crypto"
|
"github.com/tendermint/go-crypto"
|
||||||
|
|
|
@ -3,9 +3,10 @@ package main
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/tendermint/tmlibs/cli"
|
||||||
|
|
||||||
"github.com/tendermint/basecoin/app"
|
"github.com/tendermint/basecoin/app"
|
||||||
"github.com/tendermint/basecoin/cmd/basecoin/commands"
|
"github.com/tendermint/basecoin/cmd/basecoin/commands"
|
||||||
"github.com/tendermint/tmlibs/cli"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
|
@ -39,8 +39,8 @@ func main() {
|
||||||
// Prepare queries
|
// Prepare queries
|
||||||
proofs.RootCmd.AddCommand(
|
proofs.RootCmd.AddCommand(
|
||||||
// These are default parsers, optional in your app
|
// These are default parsers, optional in your app
|
||||||
proofs.TxCmd,
|
proofs.TxQueryCmd,
|
||||||
proofs.KeyCmd,
|
proofs.KeyQueryCmd,
|
||||||
coincmd.AccountQueryCmd,
|
coincmd.AccountQueryCmd,
|
||||||
noncecmd.NonceQueryCmd,
|
noncecmd.NonceQueryCmd,
|
||||||
|
|
||||||
|
|
|
@ -5,27 +5,17 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
|
|
||||||
abci "github.com/tendermint/abci/types"
|
abci "github.com/tendermint/abci/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errDecoding = fmt.Errorf("Error decoding input")
|
errDecoding = fmt.Errorf("Error decoding input")
|
||||||
errUnauthorized = fmt.Errorf("Unauthorized")
|
errUnauthorized = fmt.Errorf("Unauthorized")
|
||||||
errInvalidSignature = fmt.Errorf("Invalid Signature")
|
errTooLarge = fmt.Errorf("Input size too large")
|
||||||
errTooLarge = fmt.Errorf("Input size too large")
|
errMissingSignature = fmt.Errorf("Signature missing")
|
||||||
errNoSigners = fmt.Errorf("There are no signers")
|
errUnknownTxType = fmt.Errorf("Tx type unknown")
|
||||||
errMissingSignature = fmt.Errorf("Signature missing")
|
errInvalidFormat = fmt.Errorf("Invalid format")
|
||||||
errTooManySignatures = fmt.Errorf("Too many signatures")
|
errUnknownModule = fmt.Errorf("Unknown module")
|
||||||
errNoChain = fmt.Errorf("No chain id provided")
|
|
||||||
errTxEmpty = fmt.Errorf("The provided Tx is empty")
|
|
||||||
errWrongChain = fmt.Errorf("Wrong chain for tx")
|
|
||||||
errUnknownTxType = fmt.Errorf("Tx type unknown")
|
|
||||||
errInvalidFormat = fmt.Errorf("Invalid format")
|
|
||||||
errUnknownModule = fmt.Errorf("Unknown module")
|
|
||||||
errExpired = fmt.Errorf("Tx expired")
|
|
||||||
errUnknownKey = fmt.Errorf("Unknown key")
|
|
||||||
|
|
||||||
internalErr = abci.CodeType_InternalError
|
internalErr = abci.CodeType_InternalError
|
||||||
encodingErr = abci.CodeType_EncodingError
|
encodingErr = abci.CodeType_EncodingError
|
||||||
|
@ -70,14 +60,6 @@ func IsUnknownModuleErr(err error) bool {
|
||||||
return IsSameError(errUnknownModule, err)
|
return IsSameError(errUnknownModule, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ErrUnknownKey(mod string) TMError {
|
|
||||||
w := errors.Wrap(errUnknownKey, mod)
|
|
||||||
return WithCode(w, abci.CodeType_UnknownRequest)
|
|
||||||
}
|
|
||||||
func IsUnknownKeyErr(err error) bool {
|
|
||||||
return IsSameError(errUnknownKey, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ErrInternal(msg string) TMError {
|
func ErrInternal(msg string) TMError {
|
||||||
return New(msg, internalErr)
|
return New(msg, internalErr)
|
||||||
}
|
}
|
||||||
|
@ -104,10 +86,6 @@ func IsUnauthorizedErr(err error) bool {
|
||||||
return HasErrorCode(err, unauthorized)
|
return HasErrorCode(err, unauthorized)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ErrNoSigners() TMError {
|
|
||||||
return WithCode(errNoSigners, unauthorized)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ErrMissingSignature() TMError {
|
func ErrMissingSignature() TMError {
|
||||||
return WithCode(errMissingSignature, unauthorized)
|
return WithCode(errMissingSignature, unauthorized)
|
||||||
}
|
}
|
||||||
|
@ -115,49 +93,9 @@ func IsMissingSignatureErr(err error) bool {
|
||||||
return IsSameError(errMissingSignature, err)
|
return IsSameError(errMissingSignature, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ErrTooManySignatures() TMError {
|
|
||||||
return WithCode(errTooManySignatures, unauthorized)
|
|
||||||
}
|
|
||||||
func IsTooManySignaturesErr(err error) bool {
|
|
||||||
return IsSameError(errTooManySignatures, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ErrInvalidSignature() TMError {
|
|
||||||
return WithCode(errInvalidSignature, unauthorized)
|
|
||||||
}
|
|
||||||
func IsInvalidSignatureErr(err error) bool {
|
|
||||||
return IsSameError(errInvalidSignature, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ErrNoChain() TMError {
|
|
||||||
return WithCode(errNoChain, unauthorized)
|
|
||||||
}
|
|
||||||
func IsNoChainErr(err error) bool {
|
|
||||||
return IsSameError(errNoChain, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ErrTxEmpty() TMError {
|
|
||||||
return WithCode(errTxEmpty, unauthorized)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ErrWrongChain(chain string) TMError {
|
|
||||||
msg := errors.Wrap(errWrongChain, chain)
|
|
||||||
return WithCode(msg, unauthorized)
|
|
||||||
}
|
|
||||||
func IsWrongChainErr(err error) bool {
|
|
||||||
return IsSameError(errWrongChain, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ErrTooLarge() TMError {
|
func ErrTooLarge() TMError {
|
||||||
return WithCode(errTooLarge, encodingErr)
|
return WithCode(errTooLarge, encodingErr)
|
||||||
}
|
}
|
||||||
func IsTooLargeErr(err error) bool {
|
func IsTooLargeErr(err error) bool {
|
||||||
return IsSameError(errTooLarge, err)
|
return IsSameError(errTooLarge, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ErrExpired() TMError {
|
|
||||||
return WithCode(errExpired, unauthorized)
|
|
||||||
}
|
|
||||||
func IsExpiredErr(err error) bool {
|
|
||||||
return IsSameError(errExpired, err)
|
|
||||||
}
|
|
||||||
|
|
|
@ -42,7 +42,6 @@ func TestErrorMatches(t *testing.T) {
|
||||||
{errUnauthorized, ErrUnauthorized(), true},
|
{errUnauthorized, ErrUnauthorized(), true},
|
||||||
{errMissingSignature, ErrUnauthorized(), false},
|
{errMissingSignature, ErrUnauthorized(), false},
|
||||||
{errMissingSignature, ErrMissingSignature(), true},
|
{errMissingSignature, ErrMissingSignature(), true},
|
||||||
{errWrongChain, ErrWrongChain("hakz"), true},
|
|
||||||
{errUnknownTxType, ErrUnknownTxType(holder{}), true},
|
{errUnknownTxType, ErrUnknownTxType(holder{}), true},
|
||||||
{errUnknownTxType, ErrUnknownTxType("some text here..."), true},
|
{errUnknownTxType, ErrUnknownTxType("some text here..."), true},
|
||||||
{errUnknownTxType, ErrUnknownTxType(demoTx{5}.Wrap()), true},
|
{errUnknownTxType, ErrUnknownTxType(demoTx{5}.Wrap()), true},
|
||||||
|
@ -66,13 +65,6 @@ func TestChecks(t *testing.T) {
|
||||||
{ErrDecoding(), IsDecodingErr, true},
|
{ErrDecoding(), IsDecodingErr, true},
|
||||||
{ErrUnauthorized(), IsDecodingErr, false},
|
{ErrUnauthorized(), IsDecodingErr, false},
|
||||||
{ErrUnauthorized(), IsUnauthorizedErr, true},
|
{ErrUnauthorized(), IsUnauthorizedErr, true},
|
||||||
{ErrInvalidSignature(), IsInvalidSignatureErr, true},
|
|
||||||
// unauthorized includes InvalidSignature, but not visa versa
|
|
||||||
{ErrInvalidSignature(), IsUnauthorizedErr, true},
|
|
||||||
{ErrUnauthorized(), IsInvalidSignatureErr, false},
|
|
||||||
// make sure WrongChain works properly
|
|
||||||
{ErrWrongChain("fooz"), IsUnauthorizedErr, true},
|
|
||||||
{ErrWrongChain("barz"), IsWrongChainErr, true},
|
|
||||||
// make sure lots of things match InternalErr, but not everything
|
// make sure lots of things match InternalErr, but not everything
|
||||||
{ErrInternal("bad db connection"), IsInternalErr, true},
|
{ErrInternal("bad db connection"), IsInternalErr, true},
|
||||||
{Wrap(errors.New("wrapped")), IsInternalErr, true},
|
{Wrap(errors.New("wrapped")), IsInternalErr, true},
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
//nolint
|
||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
abci "github.com/tendermint/abci/types"
|
||||||
|
|
||||||
|
"github.com/tendermint/basecoin/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
errInvalidSignature = fmt.Errorf("Invalid Signature") //move auth
|
||||||
|
errTooManySignatures = fmt.Errorf("Too many signatures") //move auth
|
||||||
|
|
||||||
|
unauthorized = abci.CodeType_Unauthorized
|
||||||
|
)
|
||||||
|
|
||||||
|
func ErrTooManySignatures() errors.TMError {
|
||||||
|
return errors.WithCode(errTooManySignatures, unauthorized)
|
||||||
|
}
|
||||||
|
func IsTooManySignaturesErr(err error) bool {
|
||||||
|
return errors.IsSameError(errTooManySignatures, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ErrInvalidSignature() errors.TMError {
|
||||||
|
return errors.WithCode(errInvalidSignature, unauthorized)
|
||||||
|
}
|
||||||
|
func IsInvalidSignatureErr(err error) bool {
|
||||||
|
return errors.IsSameError(errInvalidSignature, err)
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/tendermint/basecoin/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestChecks(t *testing.T) {
|
||||||
|
// TODO: make sure the Is and Err methods match
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
cases := []struct {
|
||||||
|
err error
|
||||||
|
check func(error) bool
|
||||||
|
match bool
|
||||||
|
}{
|
||||||
|
// unauthorized includes InvalidSignature, but not visa versa
|
||||||
|
{ErrInvalidSignature(), IsInvalidSignatureErr, true},
|
||||||
|
{ErrInvalidSignature(), errors.IsUnauthorizedErr, true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tc := range cases {
|
||||||
|
match := tc.check(tc.err)
|
||||||
|
assert.Equal(tc.match, match, "%d", i)
|
||||||
|
}
|
||||||
|
}
|
|
@ -106,7 +106,7 @@ func (s *OneSig) Sign(pubkey crypto.PubKey, sig crypto.Signature) error {
|
||||||
return errors.ErrMissingSignature()
|
return errors.ErrMissingSignature()
|
||||||
}
|
}
|
||||||
if !s.Empty() {
|
if !s.Empty() {
|
||||||
return errors.ErrTooManySignatures()
|
return ErrTooManySignatures()
|
||||||
}
|
}
|
||||||
// set the value once we are happy
|
// set the value once we are happy
|
||||||
s.Signed = signed
|
s.Signed = signed
|
||||||
|
@ -121,7 +121,7 @@ func (s *OneSig) Signers() ([]crypto.PubKey, error) {
|
||||||
return nil, errors.ErrMissingSignature()
|
return nil, errors.ErrMissingSignature()
|
||||||
}
|
}
|
||||||
if !s.Pubkey.VerifyBytes(s.SignBytes(), s.Sig) {
|
if !s.Pubkey.VerifyBytes(s.SignBytes(), s.Sig) {
|
||||||
return nil, errors.ErrInvalidSignature()
|
return nil, ErrInvalidSignature()
|
||||||
}
|
}
|
||||||
return []crypto.PubKey{s.Pubkey}, nil
|
return []crypto.PubKey{s.Pubkey}, nil
|
||||||
}
|
}
|
||||||
|
@ -194,7 +194,7 @@ func (s *MultiSig) Signers() ([]crypto.PubKey, error) {
|
||||||
for i := range s.Sigs {
|
for i := range s.Sigs {
|
||||||
ms := s.Sigs[i]
|
ms := s.Sigs[i]
|
||||||
if !ms.Pubkey.VerifyBytes(data, ms.Sig) {
|
if !ms.Pubkey.VerifyBytes(data, ms.Sig) {
|
||||||
return nil, errors.ErrInvalidSignature()
|
return nil, ErrInvalidSignature()
|
||||||
}
|
}
|
||||||
keys[i] = ms.Pubkey
|
keys[i] = ms.Pubkey
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/tendermint/basecoin/stack"
|
|
||||||
crypto "github.com/tendermint/go-crypto"
|
crypto "github.com/tendermint/go-crypto"
|
||||||
keys "github.com/tendermint/go-crypto/keys"
|
keys "github.com/tendermint/go-crypto/keys"
|
||||||
"github.com/tendermint/go-crypto/keys/cryptostore"
|
"github.com/tendermint/go-crypto/keys/cryptostore"
|
||||||
|
@ -14,6 +13,7 @@ import (
|
||||||
wire "github.com/tendermint/go-wire"
|
wire "github.com/tendermint/go-wire"
|
||||||
|
|
||||||
"github.com/tendermint/basecoin"
|
"github.com/tendermint/basecoin"
|
||||||
|
"github.com/tendermint/basecoin/stack"
|
||||||
)
|
)
|
||||||
|
|
||||||
func checkSignBytes(t *testing.T, bytes []byte, expected string) {
|
func checkSignBytes(t *testing.T, bytes []byte, expected string) {
|
||||||
|
|
|
@ -2,7 +2,6 @@ package base
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/tendermint/basecoin"
|
"github.com/tendermint/basecoin"
|
||||||
"github.com/tendermint/basecoin/errors"
|
|
||||||
"github.com/tendermint/basecoin/stack"
|
"github.com/tendermint/basecoin/stack"
|
||||||
"github.com/tendermint/basecoin/state"
|
"github.com/tendermint/basecoin/state"
|
||||||
)
|
)
|
||||||
|
@ -48,7 +47,7 @@ func (c Chain) checkChainTx(chainID string, height uint64, tx basecoin.Tx) (base
|
||||||
// make sure it is a chaintx
|
// make sure it is a chaintx
|
||||||
ctx, ok := tx.Unwrap().(ChainTx)
|
ctx, ok := tx.Unwrap().(ChainTx)
|
||||||
if !ok {
|
if !ok {
|
||||||
return tx, errors.ErrNoChain()
|
return tx, ErrNoChain()
|
||||||
}
|
}
|
||||||
|
|
||||||
// basic validation
|
// basic validation
|
||||||
|
@ -59,10 +58,10 @@ func (c Chain) checkChainTx(chainID string, height uint64, tx basecoin.Tx) (base
|
||||||
|
|
||||||
// compare against state
|
// compare against state
|
||||||
if ctx.ChainID != chainID {
|
if ctx.ChainID != chainID {
|
||||||
return tx, errors.ErrWrongChain(ctx.ChainID)
|
return tx, ErrWrongChain(ctx.ChainID)
|
||||||
}
|
}
|
||||||
if ctx.ExpiresAt != 0 && ctx.ExpiresAt <= height {
|
if ctx.ExpiresAt != 0 && ctx.ExpiresAt <= height {
|
||||||
return tx, errors.ErrExpired()
|
return tx, ErrExpired()
|
||||||
}
|
}
|
||||||
return ctx.Tx, nil
|
return ctx.Tx, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,8 @@ import (
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
"github.com/tendermint/basecoin/client/commands"
|
|
||||||
|
|
||||||
"github.com/tendermint/basecoin"
|
"github.com/tendermint/basecoin"
|
||||||
|
"github.com/tendermint/basecoin/client/commands"
|
||||||
txcmd "github.com/tendermint/basecoin/client/commands/txs"
|
txcmd "github.com/tendermint/basecoin/client/commands/txs"
|
||||||
"github.com/tendermint/basecoin/modules/base"
|
"github.com/tendermint/basecoin/modules/base"
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
//nolint
|
||||||
|
package base
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
abci "github.com/tendermint/abci/types"
|
||||||
|
|
||||||
|
"github.com/tendermint/basecoin/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
errNoChain = fmt.Errorf("No chain id provided") //move base
|
||||||
|
errWrongChain = fmt.Errorf("Wrong chain for tx") //move base
|
||||||
|
errExpired = fmt.Errorf("Tx expired") //move base
|
||||||
|
|
||||||
|
unauthorized = abci.CodeType_Unauthorized
|
||||||
|
)
|
||||||
|
|
||||||
|
func ErrNoChain() errors.TMError {
|
||||||
|
return errors.WithCode(errNoChain, unauthorized)
|
||||||
|
}
|
||||||
|
func IsNoChainErr(err error) bool {
|
||||||
|
return errors.IsSameError(errNoChain, err)
|
||||||
|
}
|
||||||
|
func ErrWrongChain(chain string) errors.TMError {
|
||||||
|
return errors.WithMessage(chain, errWrongChain, unauthorized)
|
||||||
|
}
|
||||||
|
func IsWrongChainErr(err error) bool {
|
||||||
|
return errors.IsSameError(errWrongChain, err)
|
||||||
|
}
|
||||||
|
func ErrExpired() errors.TMError {
|
||||||
|
return errors.WithCode(errExpired, unauthorized)
|
||||||
|
}
|
||||||
|
func IsExpiredErr(err error) bool {
|
||||||
|
return errors.IsSameError(errExpired, err)
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
package base
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/tendermint/basecoin/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestErrorMatches(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
cases := []struct {
|
||||||
|
pattern, err error
|
||||||
|
match bool
|
||||||
|
}{
|
||||||
|
{errWrongChain, ErrWrongChain("hakz"), true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tc := range cases {
|
||||||
|
same := errors.IsSameError(tc.pattern, tc.err)
|
||||||
|
assert.Equal(tc.match, same, "%d: %#v / %#v", i, tc.pattern, tc.err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestChecks(t *testing.T) {
|
||||||
|
// TODO: make sure the Is and Err methods match
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
cases := []struct {
|
||||||
|
err error
|
||||||
|
check func(error) bool
|
||||||
|
match bool
|
||||||
|
}{
|
||||||
|
// make sure WrongChain works properly
|
||||||
|
{ErrWrongChain("fooz"), errors.IsUnauthorizedErr, true},
|
||||||
|
{ErrWrongChain("barz"), IsWrongChainErr, true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tc := range cases {
|
||||||
|
match := tc.check(tc.err)
|
||||||
|
assert.Equal(tc.match, match, "%d", i)
|
||||||
|
}
|
||||||
|
}
|
|
@ -86,10 +86,10 @@ func (c ChainTx) Wrap() basecoin.Tx {
|
||||||
}
|
}
|
||||||
func (c ChainTx) ValidateBasic() error {
|
func (c ChainTx) ValidateBasic() error {
|
||||||
if c.ChainID == "" {
|
if c.ChainID == "" {
|
||||||
return errors.ErrNoChain()
|
return ErrNoChain()
|
||||||
}
|
}
|
||||||
if !chainPattern.MatchString(c.ChainID) {
|
if !chainPattern.MatchString(c.ChainID) {
|
||||||
return errors.ErrWrongChain(c.ChainID)
|
return ErrWrongChain(c.ChainID)
|
||||||
}
|
}
|
||||||
if c.Tx.Empty() {
|
if c.Tx.Empty() {
|
||||||
return errors.ErrUnknownTxType(c.Tx)
|
return errors.ErrUnknownTxType(c.Tx)
|
||||||
|
|
|
@ -7,10 +7,10 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/tendermint/basecoin/stack"
|
|
||||||
"github.com/tendermint/go-wire/data"
|
"github.com/tendermint/go-wire/data"
|
||||||
|
|
||||||
"github.com/tendermint/basecoin"
|
"github.com/tendermint/basecoin"
|
||||||
|
"github.com/tendermint/basecoin/stack"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestEncoding(t *testing.T) {
|
func TestEncoding(t *testing.T) {
|
||||||
|
|
|
@ -5,9 +5,9 @@ import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
lc "github.com/tendermint/light-client"
|
lc "github.com/tendermint/light-client"
|
||||||
|
|
||||||
lcmd "github.com/tendermint/basecoin/client/commands"
|
lcmd "github.com/tendermint/basecoin/client/commands"
|
||||||
proofcmd "github.com/tendermint/basecoin/client/commands/proofs"
|
proofcmd "github.com/tendermint/basecoin/client/commands/proofs"
|
||||||
|
|
||||||
"github.com/tendermint/basecoin/modules/auth"
|
"github.com/tendermint/basecoin/modules/auth"
|
||||||
"github.com/tendermint/basecoin/modules/coin"
|
"github.com/tendermint/basecoin/modules/coin"
|
||||||
"github.com/tendermint/basecoin/stack"
|
"github.com/tendermint/basecoin/stack"
|
||||||
|
@ -17,10 +17,10 @@ import (
|
||||||
var AccountQueryCmd = &cobra.Command{
|
var AccountQueryCmd = &cobra.Command{
|
||||||
Use: "account [address]",
|
Use: "account [address]",
|
||||||
Short: "Get details of an account, with proof",
|
Short: "Get details of an account, with proof",
|
||||||
RunE: lcmd.RequireInit(doAccountQuery),
|
RunE: lcmd.RequireInit(accountQueryCmd),
|
||||||
}
|
}
|
||||||
|
|
||||||
func doAccountQuery(cmd *cobra.Command, args []string) error {
|
func accountQueryCmd(cmd *cobra.Command, args []string) error {
|
||||||
addr, err := proofcmd.ParseHexKey(args, "address")
|
addr, err := proofcmd.ParseHexKey(args, "address")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -14,7 +14,7 @@ import (
|
||||||
var SendTxCmd = &cobra.Command{
|
var SendTxCmd = &cobra.Command{
|
||||||
Use: "send",
|
Use: "send",
|
||||||
Short: "send tokens from one account to another",
|
Short: "send tokens from one account to another",
|
||||||
RunE: commands.RequireInit(doSendTx),
|
RunE: commands.RequireInit(sendTxCmd),
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint
|
//nolint
|
||||||
|
@ -31,8 +31,8 @@ func init() {
|
||||||
flags.String(FlagFrom, "", "Address sending coins, if not first signer")
|
flags.String(FlagFrom, "", "Address sending coins, if not first signer")
|
||||||
}
|
}
|
||||||
|
|
||||||
// doSendTx is an example of how to make a tx
|
// sendTxCmd is an example of how to make a tx
|
||||||
func doSendTx(cmd *cobra.Command, args []string) error {
|
func sendTxCmd(cmd *cobra.Command, args []string) error {
|
||||||
// load data from json or flags
|
// load data from json or flags
|
||||||
// var tx basecoin.Tx
|
// var tx basecoin.Tx
|
||||||
// found, err := txcmd.LoadJSON(&tx)
|
// found, err := txcmd.LoadJSON(&tx)
|
||||||
|
|
|
@ -5,23 +5,23 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
abci "github.com/tendermint/abci/types"
|
abci "github.com/tendermint/abci/types"
|
||||||
|
|
||||||
"github.com/tendermint/basecoin/errors"
|
"github.com/tendermint/basecoin/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errNoAccount = fmt.Errorf("No such account")
|
errNoAccount = fmt.Errorf("No such account")
|
||||||
errInsufficientFunds = fmt.Errorf("Insufficient Funds")
|
errInsufficientFunds = fmt.Errorf("Insufficient funds")
|
||||||
errNoInputs = fmt.Errorf("No Input Coins")
|
errNoInputs = fmt.Errorf("No input coins")
|
||||||
errNoOutputs = fmt.Errorf("No Output Coins")
|
errNoOutputs = fmt.Errorf("No output coins")
|
||||||
errInvalidAddress = fmt.Errorf("Invalid Address")
|
errInvalidAddress = fmt.Errorf("Invalid address")
|
||||||
errInvalidCoins = fmt.Errorf("Invalid Coins")
|
errInvalidCoins = fmt.Errorf("Invalid coins")
|
||||||
errInvalidSequence = fmt.Errorf("Invalid Sequence")
|
errUnknownKey = fmt.Errorf("Unknown key")
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
invalidInput = abci.CodeType_BaseInvalidInput
|
invalidInput = abci.CodeType_BaseInvalidInput
|
||||||
invalidOutput = abci.CodeType_BaseInvalidOutput
|
invalidOutput = abci.CodeType_BaseInvalidOutput
|
||||||
unknownAddress = abci.CodeType_BaseUnknownAddress
|
unknownAddress = abci.CodeType_BaseUnknownAddress
|
||||||
|
unknownRequest = abci.CodeType_UnknownRequest
|
||||||
)
|
)
|
||||||
|
|
||||||
// here are some generic handlers to grab classes of errors based on code
|
// here are some generic handlers to grab classes of errors based on code
|
||||||
|
@ -80,3 +80,10 @@ func ErrNoOutputs() errors.TMError {
|
||||||
func IsNoOutputsErr(err error) bool {
|
func IsNoOutputsErr(err error) bool {
|
||||||
return errors.IsSameError(errNoOutputs, err)
|
return errors.IsSameError(errNoOutputs, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ErrUnknownKey(mod string) errors.TMError {
|
||||||
|
return errors.WithMessage(mod, errUnknownKey, unknownRequest)
|
||||||
|
}
|
||||||
|
func IsUnknownKeyErr(err error) bool {
|
||||||
|
return errors.IsSameError(errUnknownKey, err)
|
||||||
|
}
|
||||||
|
|
|
@ -99,7 +99,7 @@ func (h Handler) SetOption(l log.Logger, store state.KVStore, module, key, value
|
||||||
return "Success", nil
|
return "Success", nil
|
||||||
|
|
||||||
}
|
}
|
||||||
return "", errors.ErrUnknownKey(key)
|
return "", ErrUnknownKey(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkTx(ctx basecoin.Context, tx basecoin.Tx) (send SendTx, err error) {
|
func checkTx(ctx basecoin.Context, tx basecoin.Tx) (send SendTx, err error) {
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package coin
|
package coin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/tendermint/basecoin/modules/auth"
|
|
||||||
crypto "github.com/tendermint/go-crypto"
|
crypto "github.com/tendermint/go-crypto"
|
||||||
"github.com/tendermint/go-wire/data"
|
"github.com/tendermint/go-wire/data"
|
||||||
|
|
||||||
"github.com/tendermint/basecoin"
|
"github.com/tendermint/basecoin"
|
||||||
|
"github.com/tendermint/basecoin/modules/auth"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AccountWithKey is a helper for tests, that includes and account
|
// AccountWithKey is a helper for tests, that includes and account
|
||||||
|
|
|
@ -10,19 +10,21 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errInsufficientFees = fmt.Errorf("Insufficient Fees")
|
errInsufficientFees = fmt.Errorf("Insufficient fees")
|
||||||
errWrongFeeDenom = fmt.Errorf("Required fee denomination")
|
errWrongFeeDenom = fmt.Errorf("Required fee denomination")
|
||||||
|
|
||||||
|
invalidInput = abci.CodeType_BaseInvalidInput
|
||||||
)
|
)
|
||||||
|
|
||||||
func ErrInsufficientFees() errors.TMError {
|
func ErrInsufficientFees() errors.TMError {
|
||||||
return errors.WithCode(errInsufficientFees, abci.CodeType_BaseInvalidInput)
|
return errors.WithCode(errInsufficientFees, invalidInput)
|
||||||
}
|
}
|
||||||
func IsInsufficientFeesErr(err error) bool {
|
func IsInsufficientFeesErr(err error) bool {
|
||||||
return errors.IsSameError(errInsufficientFees, err)
|
return errors.IsSameError(errInsufficientFees, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ErrWrongFeeDenom(denom string) errors.TMError {
|
func ErrWrongFeeDenom(denom string) errors.TMError {
|
||||||
return errors.WithMessage(denom, errWrongFeeDenom, abci.CodeType_BaseInvalidInput)
|
return errors.WithMessage(denom, errWrongFeeDenom, invalidInput)
|
||||||
}
|
}
|
||||||
func IsWrongFeeDenomErr(err error) bool {
|
func IsWrongFeeDenomErr(err error) bool {
|
||||||
return errors.IsSameError(errWrongFeeDenom, err)
|
return errors.IsSameError(errWrongFeeDenom, err)
|
||||||
|
|
|
@ -7,9 +7,10 @@ import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
lc "github.com/tendermint/light-client"
|
lc "github.com/tendermint/light-client"
|
||||||
|
|
||||||
|
"github.com/tendermint/basecoin"
|
||||||
lcmd "github.com/tendermint/basecoin/client/commands"
|
lcmd "github.com/tendermint/basecoin/client/commands"
|
||||||
proofcmd "github.com/tendermint/basecoin/client/commands/proofs"
|
proofcmd "github.com/tendermint/basecoin/client/commands/proofs"
|
||||||
|
|
||||||
"github.com/tendermint/basecoin/modules/nonce"
|
"github.com/tendermint/basecoin/modules/nonce"
|
||||||
"github.com/tendermint/basecoin/stack"
|
"github.com/tendermint/basecoin/stack"
|
||||||
)
|
)
|
||||||
|
@ -18,28 +19,36 @@ import (
|
||||||
var NonceQueryCmd = &cobra.Command{
|
var NonceQueryCmd = &cobra.Command{
|
||||||
Use: "nonce [address]",
|
Use: "nonce [address]",
|
||||||
Short: "Get details of a nonce sequence number, with proof",
|
Short: "Get details of a nonce sequence number, with proof",
|
||||||
RunE: lcmd.RequireInit(doNonceQuery),
|
RunE: lcmd.RequireInit(nonceQueryCmd),
|
||||||
}
|
}
|
||||||
|
|
||||||
func doNonceQuery(cmd *cobra.Command, args []string) error {
|
func nonceQueryCmd(cmd *cobra.Command, args []string) error {
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
return errors.New("Missing required argument [address]")
|
return errors.New("Missing required argument [address]")
|
||||||
}
|
}
|
||||||
addr := strings.Join(args, ",")
|
addr := strings.Join(args, ",")
|
||||||
act, err := parseActors(addr)
|
|
||||||
|
signers, err := parseActors(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
key := stack.PrefixedKey(nonce.NameNonce, nonce.GetSeqKey(act))
|
seq, proof, err := doNonceQuery(signers)
|
||||||
|
if err != nil {
|
||||||
var seq uint32
|
|
||||||
proof, err := proofcmd.GetAndParseAppProof(key, &seq)
|
|
||||||
if lc.IsNoDataErr(err) {
|
|
||||||
return errors.Errorf("Sequence is empty for address %s ", addr)
|
|
||||||
} else if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return proofcmd.OutputProof(seq, proof.BlockHeight())
|
return proofcmd.OutputProof(seq, proof.BlockHeight())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func doNonceQuery(signers []basecoin.Actor) (sequence uint32, proof lc.Proof, err error) {
|
||||||
|
|
||||||
|
key := stack.PrefixedKey(nonce.NameNonce, nonce.GetSeqKey(signers))
|
||||||
|
|
||||||
|
proof, err = proofcmd.GetAndParseAppProof(key, &sequence)
|
||||||
|
if lc.IsNoDataErr(err) {
|
||||||
|
err = errors.Errorf("Sequence is empty for key %s ", key)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -28,15 +28,17 @@ var _ txcmd.Wrapper = NonceWrapper{}
|
||||||
// the tx with this nonce. Grabs the permission from the signer,
|
// the tx with this nonce. Grabs the permission from the signer,
|
||||||
// as we still only support single sig on the cli
|
// as we still only support single sig on the cli
|
||||||
func (NonceWrapper) Wrap(tx basecoin.Tx) (res basecoin.Tx, err error) {
|
func (NonceWrapper) Wrap(tx basecoin.Tx) (res basecoin.Tx, err error) {
|
||||||
seq, err := readSequence()
|
|
||||||
if err != nil {
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
signers, err := readNonceKey()
|
signers, err := readNonceKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
seq, err := readSequence(signers)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
res = nonce.NewTx(seq, signers, tx)
|
res = nonce.NewTx(seq, signers, tx)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -67,13 +69,28 @@ func parseActors(key string) (signers []basecoin.Actor, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func readSequence() (uint32, error) {
|
// read the sequence from the flag or query for it if flag is -1
|
||||||
|
func readSequence(signers []basecoin.Actor) (seq uint32, err error) {
|
||||||
//add the nonce tx layer to the tx
|
//add the nonce tx layer to the tx
|
||||||
seq := viper.GetInt(FlagSequence)
|
seqFlag := viper.GetInt(FlagSequence)
|
||||||
if seq > 0 {
|
|
||||||
return uint32(seq), nil
|
switch {
|
||||||
|
case seqFlag > 0:
|
||||||
|
seq = uint32(seqFlag)
|
||||||
|
|
||||||
|
case seqFlag == -1:
|
||||||
|
//autocalculation for default sequence
|
||||||
|
seq, _, err = doNonceQuery(signers)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//increase the sequence by 1!
|
||||||
|
seq++
|
||||||
|
|
||||||
|
default:
|
||||||
|
err = fmt.Errorf("sequence must be either greater than 0, or -1 for autocalculation")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: try to download from query..
|
return
|
||||||
return 0, fmt.Errorf("sequence must be greater than 0")
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,22 +11,31 @@ import (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errNoNonce = fmt.Errorf("Tx doesn't contain nonce")
|
errNoNonce = fmt.Errorf("Tx doesn't contain nonce")
|
||||||
errNotMember = fmt.Errorf("nonce contains non-permissioned member")
|
errNotMember = fmt.Errorf("Nonce contains non-permissioned member")
|
||||||
errZeroSequence = fmt.Errorf("Sequence number cannot be zero")
|
errZeroSequence = fmt.Errorf("Sequence number cannot be zero")
|
||||||
|
errNoSigners = fmt.Errorf("There are no signers")
|
||||||
|
errTxEmpty = fmt.Errorf("The provided Tx is empty")
|
||||||
|
|
||||||
unauthorized = abci.CodeType_Unauthorized
|
unauthorized = abci.CodeType_Unauthorized
|
||||||
|
badNonce = abci.CodeType_BadNonce
|
||||||
|
invalidInput = abci.CodeType_BaseInvalidInput
|
||||||
)
|
)
|
||||||
|
|
||||||
func ErrBadNonce(got, expected uint32) errors.TMError {
|
func ErrBadNonce(got, expected uint32) errors.TMError {
|
||||||
return errors.WithCode(fmt.Errorf("Bad nonce sequence, got %d, expected %d", got, expected), unauthorized)
|
return errors.WithCode(fmt.Errorf("Bad nonce sequence, got %d, expected %d", got, expected), badNonce)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ErrNoNonce() errors.TMError {
|
func ErrNoNonce() errors.TMError {
|
||||||
return errors.WithCode(errNoNonce, unauthorized)
|
return errors.WithCode(errNoNonce, badNonce)
|
||||||
}
|
}
|
||||||
func ErrNotMember() errors.TMError {
|
func ErrNotMember() errors.TMError {
|
||||||
return errors.WithCode(errNotMember, unauthorized)
|
return errors.WithCode(errNotMember, unauthorized)
|
||||||
}
|
}
|
||||||
func ErrZeroSequence() errors.TMError {
|
func ErrZeroSequence() errors.TMError {
|
||||||
return errors.WithCode(errZeroSequence, unauthorized)
|
return errors.WithCode(errZeroSequence, invalidInput)
|
||||||
|
}
|
||||||
|
func ErrNoSigners() errors.TMError {
|
||||||
|
return errors.WithCode(errNoSigners, invalidInput)
|
||||||
|
}
|
||||||
|
func ErrTxEmpty() errors.TMError {
|
||||||
|
return errors.WithCode(errTxEmpty, invalidInput)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/tendermint/basecoin"
|
"github.com/tendermint/basecoin"
|
||||||
"github.com/tendermint/basecoin/errors"
|
|
||||||
"github.com/tendermint/basecoin/state"
|
"github.com/tendermint/basecoin/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -50,11 +49,11 @@ func (n Tx) Wrap() basecoin.Tx {
|
||||||
func (n Tx) ValidateBasic() error {
|
func (n Tx) ValidateBasic() error {
|
||||||
switch {
|
switch {
|
||||||
case n.Tx.Empty():
|
case n.Tx.Empty():
|
||||||
return errors.ErrTxEmpty()
|
return ErrTxEmpty()
|
||||||
case n.Sequence == 0:
|
case n.Sequence == 0:
|
||||||
return ErrZeroSequence()
|
return ErrZeroSequence()
|
||||||
case len(n.Signers) == 0:
|
case len(n.Signers) == 0:
|
||||||
return errors.ErrNoSigners()
|
return ErrNoSigners()
|
||||||
}
|
}
|
||||||
return n.Tx.ValidateBasic()
|
return n.Tx.ValidateBasic()
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
abci "github.com/tendermint/abci/types"
|
abci "github.com/tendermint/abci/types"
|
||||||
|
|
||||||
"github.com/tendermint/basecoin/errors"
|
"github.com/tendermint/basecoin/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -16,54 +17,56 @@ var (
|
||||||
errNoMembers = fmt.Errorf("No members specified")
|
errNoMembers = fmt.Errorf("No members specified")
|
||||||
errTooManyMembers = fmt.Errorf("Too many members specified")
|
errTooManyMembers = fmt.Errorf("Too many members specified")
|
||||||
errNotEnoughMembers = fmt.Errorf("Not enough members specified")
|
errNotEnoughMembers = fmt.Errorf("Not enough members specified")
|
||||||
|
|
||||||
|
unauthorized = abci.CodeType_Unauthorized
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: codegen?
|
// TODO: codegen?
|
||||||
// ex: err-gen NoRole,"No such role",CodeType_Unauthorized
|
// ex: err-gen NoRole,"No such role",CodeType_Unauthorized
|
||||||
func ErrNoRole() errors.TMError {
|
func ErrNoRole() errors.TMError {
|
||||||
return errors.WithCode(errNoRole, abci.CodeType_Unauthorized)
|
return errors.WithCode(errNoRole, unauthorized)
|
||||||
}
|
}
|
||||||
func IsNoRoleErr(err error) bool {
|
func IsNoRoleErr(err error) bool {
|
||||||
return errors.IsSameError(errNoRole, err)
|
return errors.IsSameError(errNoRole, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ErrRoleExists() errors.TMError {
|
func ErrRoleExists() errors.TMError {
|
||||||
return errors.WithCode(errRoleExists, abci.CodeType_Unauthorized)
|
return errors.WithCode(errRoleExists, unauthorized)
|
||||||
}
|
}
|
||||||
func IsRoleExistsErr(err error) bool {
|
func IsRoleExistsErr(err error) bool {
|
||||||
return errors.IsSameError(errRoleExists, err)
|
return errors.IsSameError(errRoleExists, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ErrNotMember() errors.TMError {
|
func ErrNotMember() errors.TMError {
|
||||||
return errors.WithCode(errNotMember, abci.CodeType_Unauthorized)
|
return errors.WithCode(errNotMember, unauthorized)
|
||||||
}
|
}
|
||||||
func IsNotMemberErr(err error) bool {
|
func IsNotMemberErr(err error) bool {
|
||||||
return errors.IsSameError(errNotMember, err)
|
return errors.IsSameError(errNotMember, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ErrInsufficientSigs() errors.TMError {
|
func ErrInsufficientSigs() errors.TMError {
|
||||||
return errors.WithCode(errInsufficientSigs, abci.CodeType_Unauthorized)
|
return errors.WithCode(errInsufficientSigs, unauthorized)
|
||||||
}
|
}
|
||||||
func IsInsufficientSigsErr(err error) bool {
|
func IsInsufficientSigsErr(err error) bool {
|
||||||
return errors.IsSameError(errInsufficientSigs, err)
|
return errors.IsSameError(errInsufficientSigs, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ErrNoMembers() errors.TMError {
|
func ErrNoMembers() errors.TMError {
|
||||||
return errors.WithCode(errNoMembers, abci.CodeType_Unauthorized)
|
return errors.WithCode(errNoMembers, unauthorized)
|
||||||
}
|
}
|
||||||
func IsNoMembersErr(err error) bool {
|
func IsNoMembersErr(err error) bool {
|
||||||
return errors.IsSameError(errNoMembers, err)
|
return errors.IsSameError(errNoMembers, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ErrTooManyMembers() errors.TMError {
|
func ErrTooManyMembers() errors.TMError {
|
||||||
return errors.WithCode(errTooManyMembers, abci.CodeType_Unauthorized)
|
return errors.WithCode(errTooManyMembers, unauthorized)
|
||||||
}
|
}
|
||||||
func IsTooManyMembersErr(err error) bool {
|
func IsTooManyMembersErr(err error) bool {
|
||||||
return errors.IsSameError(errTooManyMembers, err)
|
return errors.IsSameError(errTooManyMembers, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ErrNotEnoughMembers() errors.TMError {
|
func ErrNotEnoughMembers() errors.TMError {
|
||||||
return errors.WithCode(errNotEnoughMembers, abci.CodeType_Unauthorized)
|
return errors.WithCode(errNotEnoughMembers, unauthorized)
|
||||||
}
|
}
|
||||||
func IsNotEnoughMembersErr(err error) bool {
|
func IsNotEnoughMembersErr(err error) bool {
|
||||||
return errors.IsSameError(errNotEnoughMembers, err)
|
return errors.IsSameError(errNotEnoughMembers, err)
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
"github.com/tendermint/basecoin"
|
"github.com/tendermint/basecoin"
|
||||||
"github.com/tendermint/basecoin/modules/roles"
|
"github.com/tendermint/basecoin/modules/roles"
|
||||||
"github.com/tendermint/basecoin/stack"
|
"github.com/tendermint/basecoin/stack"
|
||||||
|
|
|
@ -3,10 +3,11 @@ package roles
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
wire "github.com/tendermint/go-wire"
|
||||||
|
|
||||||
"github.com/tendermint/basecoin"
|
"github.com/tendermint/basecoin"
|
||||||
"github.com/tendermint/basecoin/errors"
|
"github.com/tendermint/basecoin/errors"
|
||||||
"github.com/tendermint/basecoin/state"
|
"github.com/tendermint/basecoin/state"
|
||||||
wire "github.com/tendermint/go-wire"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewPerm creates a role permission with the given label
|
// NewPerm creates a role permission with the given label
|
||||||
|
|
|
@ -6,11 +6,11 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/tendermint/go-wire/data"
|
||||||
"github.com/tendermint/tmlibs/log"
|
"github.com/tendermint/tmlibs/log"
|
||||||
|
|
||||||
"github.com/tendermint/basecoin"
|
"github.com/tendermint/basecoin"
|
||||||
"github.com/tendermint/basecoin/state"
|
"github.com/tendermint/basecoin/state"
|
||||||
"github.com/tendermint/go-wire/data"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// writerMid is a middleware that writes the given bytes on CheckTx and DeliverTx
|
// writerMid is a middleware that writes the given bytes on CheckTx and DeliverTx
|
||||||
|
|
|
@ -21,20 +21,20 @@ test00GetAccount() {
|
||||||
SENDER=$(getAddr $RICH)
|
SENDER=$(getAddr $RICH)
|
||||||
RECV=$(getAddr $POOR)
|
RECV=$(getAddr $POOR)
|
||||||
|
|
||||||
assertFalse "requires arg" "${CLIENT_EXE} query account"
|
assertFalse "line=${LINENO}, requires arg" "${CLIENT_EXE} query account"
|
||||||
|
|
||||||
checkAccount $SENDER "9007199254740992"
|
checkAccount $SENDER "9007199254740992"
|
||||||
|
|
||||||
ACCT2=$(${CLIENT_EXE} query account $RECV 2>/dev/null)
|
ACCT2=$(${CLIENT_EXE} query account $RECV 2>/dev/null)
|
||||||
assertFalse "has no genesis account" $?
|
assertFalse "line=${LINENO}, has no genesis account" $?
|
||||||
}
|
}
|
||||||
|
|
||||||
test01SendTx() {
|
test01SendTx() {
|
||||||
SENDER=$(getAddr $RICH)
|
SENDER=$(getAddr $RICH)
|
||||||
RECV=$(getAddr $POOR)
|
RECV=$(getAddr $POOR)
|
||||||
|
|
||||||
assertFalse "missing dest" "${CLIENT_EXE} tx send --amount=992mycoin --sequence=1"
|
assertFalse "line=${LINENO}, missing dest" "${CLIENT_EXE} tx send --amount=992mycoin --sequence=1"
|
||||||
assertFalse "bad password" "echo foo | ${CLIENT_EXE} tx send --amount=992mycoin --sequence=1 --to=$RECV --name=$RICH"
|
assertFalse "line=${LINENO}, bad password" "echo foo | ${CLIENT_EXE} tx send --amount=992mycoin --sequence=1 --to=$RECV --name=$RICH"
|
||||||
TX=$(echo qwertyuiop | ${CLIENT_EXE} tx send --amount=992mycoin --sequence=1 --to=$RECV --name=$RICH)
|
TX=$(echo qwertyuiop | ${CLIENT_EXE} tx send --amount=992mycoin --sequence=1 --to=$RECV --name=$RICH)
|
||||||
txSucceeded $? "$TX" "$RECV"
|
txSucceeded $? "$TX" "$RECV"
|
||||||
HASH=$(echo $TX | jq .hash | tr -d \")
|
HASH=$(echo $TX | jq .hash | tr -d \")
|
||||||
|
@ -53,7 +53,8 @@ test02SendTxWithFee() {
|
||||||
SENDER=$(getAddr $RICH)
|
SENDER=$(getAddr $RICH)
|
||||||
RECV=$(getAddr $POOR)
|
RECV=$(getAddr $POOR)
|
||||||
|
|
||||||
TX=$(echo qwertyuiop | ${CLIENT_EXE} tx send --amount=90mycoin --fee=10mycoin --sequence=2 --to=$RECV --name=$RICH)
|
# Test to see if the auto-sequencing works, the sequence here should be calculated to be 2
|
||||||
|
TX=$(echo qwertyuiop | ${CLIENT_EXE} tx send --amount=90mycoin --fee=10mycoin --sequence=-1 --to=$RECV --name=$RICH)
|
||||||
txSucceeded $? "$TX" "$RECV"
|
txSucceeded $? "$TX" "$RECV"
|
||||||
HASH=$(echo $TX | jq .hash | tr -d \")
|
HASH=$(echo $TX | jq .hash | tr -d \")
|
||||||
TX_HEIGHT=$(echo $TX | jq .height)
|
TX_HEIGHT=$(echo $TX | jq .height)
|
||||||
|
@ -67,7 +68,7 @@ test02SendTxWithFee() {
|
||||||
|
|
||||||
# assert replay protection
|
# assert replay protection
|
||||||
TX=$(echo qwertyuiop | ${CLIENT_EXE} tx send --amount=90mycoin --fee=10mycoin --sequence=2 --to=$RECV --name=$RICH 2>/dev/null)
|
TX=$(echo qwertyuiop | ${CLIENT_EXE} tx send --amount=90mycoin --fee=10mycoin --sequence=2 --to=$RECV --name=$RICH 2>/dev/null)
|
||||||
assertFalse "replay: $TX" $?
|
assertFalse "line=${LINENO}, replay: $TX" $?
|
||||||
checkAccount $SENDER "9007199254739900"
|
checkAccount $SENDER "9007199254739900"
|
||||||
checkAccount $RECV "1082"
|
checkAccount $RECV "1082"
|
||||||
|
|
||||||
|
@ -76,7 +77,7 @@ test02SendTxWithFee() {
|
||||||
if [ -n "$DEBUG" ]; then echo $NONCE; echo; fi
|
if [ -n "$DEBUG" ]; then echo $NONCE; echo; fi
|
||||||
# TODO: note that cobra returns error code 0 on parse failure,
|
# TODO: note that cobra returns error code 0 on parse failure,
|
||||||
# so currently this check passes even if there is no nonce query command
|
# so currently this check passes even if there is no nonce query command
|
||||||
if assertTrue "no nonce query" $?; then
|
if assertTrue "line=${LINENO}, no nonce query" $?; then
|
||||||
assertEquals "line=${LINENO}, proper nonce" "2" $(echo $NONCE | jq .data)
|
assertEquals "line=${LINENO}, proper nonce" "2" $(echo $NONCE | jq .data)
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,7 +141,7 @@ checkAccount() {
|
||||||
# XXX Ex Usage: txSucceeded $? "$TX" "$RECIEVER"
|
# XXX Ex Usage: txSucceeded $? "$TX" "$RECIEVER"
|
||||||
# Desc: Must be called right after the `tx` command, makes sure it got a success response
|
# Desc: Must be called right after the `tx` command, makes sure it got a success response
|
||||||
txSucceeded() {
|
txSucceeded() {
|
||||||
if (assertTrue "sent tx ($3): $2" $1); then
|
if (assertTrue "line=${LINENO}, sent tx ($3): $2" $1); then
|
||||||
TX=$2
|
TX=$2
|
||||||
assertEquals "line=${LINENO}, good check ($3): $TX" "0" $(echo $TX | jq .check_tx.code)
|
assertEquals "line=${LINENO}, good check ($3): $TX" "0" $(echo $TX | jq .check_tx.code)
|
||||||
assertEquals "line=${LINENO}, good deliver ($3): $TX" "0" $(echo $TX | jq .deliver_tx.code)
|
assertEquals "line=${LINENO}, good deliver ($3): $TX" "0" $(echo $TX | jq .deliver_tx.code)
|
||||||
|
@ -177,7 +177,7 @@ checkSendTx() {
|
||||||
# and that the first input was from this sender for this amount
|
# and that the first input was from this sender for this amount
|
||||||
checkSendFeeTx() {
|
checkSendFeeTx() {
|
||||||
TX=$(${CLIENT_EXE} query tx $1)
|
TX=$(${CLIENT_EXE} query tx $1)
|
||||||
assertTrue "found tx" $?
|
assertTrue "line=${LINENO}, found tx" $?
|
||||||
if [ -n "$DEBUG" ]; then echo $TX; echo; fi
|
if [ -n "$DEBUG" ]; then echo $TX; echo; fi
|
||||||
|
|
||||||
assertEquals "line=${LINENO}, proper height" $2 $(echo $TX | jq .height)
|
assertEquals "line=${LINENO}, proper height" $2 $(echo $TX | jq .height)
|
||||||
|
|
|
@ -104,7 +104,7 @@ test03AddCount() {
|
||||||
|
|
||||||
# make sure we cannot replay the counter, no state change
|
# make sure we cannot replay the counter, no state change
|
||||||
TX=$(echo qwertyuiop | ${CLIENT_EXE} tx counter --countfee=10mycoin --sequence=2 --name=${RICH} --valid 2>/dev/null)
|
TX=$(echo qwertyuiop | ${CLIENT_EXE} tx counter --countfee=10mycoin --sequence=2 --name=${RICH} --valid 2>/dev/null)
|
||||||
assertFalse "replay: $TX" $?
|
assertFalse "line=${LINENO}, replay: $TX" $?
|
||||||
checkCounter "2" "17"
|
checkCounter "2" "17"
|
||||||
checkAccount $SENDER "9007199254739979"
|
checkAccount $SENDER "9007199254739979"
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,21 +66,21 @@ test00GetAccount() {
|
||||||
RECV_1=$(BC_HOME=${CLIENT_1} getAddr $POOR)
|
RECV_1=$(BC_HOME=${CLIENT_1} getAddr $POOR)
|
||||||
export BC_HOME=${CLIENT_1}
|
export BC_HOME=${CLIENT_1}
|
||||||
|
|
||||||
assertFalse "requires arg" "${CLIENT_EXE} query account 2>/dev/null"
|
assertFalse "line=${LINENO}, requires arg" "${CLIENT_EXE} query account 2>/dev/null"
|
||||||
assertFalse "has no genesis account" "${CLIENT_EXE} query account $RECV_1 2>/dev/null"
|
assertFalse "line=${LINENO}, has no genesis account" "${CLIENT_EXE} query account $RECV_1 2>/dev/null"
|
||||||
checkAccount $SENDER_1 "0" "9007199254740992"
|
checkAccount $SENDER_1 "0" "9007199254740992"
|
||||||
|
|
||||||
export BC_HOME=${CLIENT_2}
|
export BC_HOME=${CLIENT_2}
|
||||||
SENDER_2=$(getAddr $RICH)
|
SENDER_2=$(getAddr $RICH)
|
||||||
RECV_2=$(getAddr $POOR)
|
RECV_2=$(getAddr $POOR)
|
||||||
|
|
||||||
assertFalse "requires arg" "${CLIENT_EXE} query account 2>/dev/null"
|
assertFalse "line=${LINENO}, requires arg" "${CLIENT_EXE} query account 2>/dev/null"
|
||||||
assertFalse "has no genesis account" "${CLIENT_EXE} query account $RECV_2 2>/dev/null"
|
assertFalse "line=${LINENO}, has no genesis account" "${CLIENT_EXE} query account $RECV_2 2>/dev/null"
|
||||||
checkAccount $SENDER_2 "0" "9007199254740992"
|
checkAccount $SENDER_2 "0" "9007199254740992"
|
||||||
|
|
||||||
# Make sure that they have different addresses on both chains (they are random keys)
|
# Make sure that they have different addresses on both chains (they are random keys)
|
||||||
assertNotEquals "sender keys must be different" "$SENDER_1" "$SENDER_2"
|
assertNotEquals "line=${LINENO}, sender keys must be different" "$SENDER_1" "$SENDER_2"
|
||||||
assertNotEquals "recipient keys must be different" "$RECV_1" "$RECV_2"
|
assertNotEquals "line=${LINENO}, recipient keys must be different" "$RECV_1" "$RECV_2"
|
||||||
}
|
}
|
||||||
|
|
||||||
test01SendIBCTx() {
|
test01SendIBCTx() {
|
||||||
|
@ -105,7 +105,7 @@ test01SendIBCTx() {
|
||||||
|
|
||||||
# Make sure nothing arrived - yet
|
# Make sure nothing arrived - yet
|
||||||
waitForBlock ${PORT_1}
|
waitForBlock ${PORT_1}
|
||||||
assertFalse "no relay running" "BC_HOME=${CLIENT_2} ${CLIENT_EXE} query account $RECV"
|
assertFalse "line=${LINENO}, no relay running" "BC_HOME=${CLIENT_2} ${CLIENT_EXE} query account $RECV"
|
||||||
|
|
||||||
# Start the relay and wait a few blocks...
|
# Start the relay and wait a few blocks...
|
||||||
# (already sent a tx on chain1, so use higher sequence)
|
# (already sent a tx on chain1, so use higher sequence)
|
||||||
|
|
|
@ -4,103 +4,103 @@ CLIENT_EXE=basecli
|
||||||
SERVER_EXE=basecoin
|
SERVER_EXE=basecoin
|
||||||
|
|
||||||
oneTimeSetUp() {
|
oneTimeSetUp() {
|
||||||
BASE=~/.bc_init_test
|
BASE=~/.bc_init_test
|
||||||
rm -rf "$BASE"
|
rm -rf "$BASE"
|
||||||
mkdir -p "$BASE"
|
mkdir -p "$BASE"
|
||||||
|
|
||||||
SERVER="${BASE}/server"
|
SERVER="${BASE}/server"
|
||||||
SERVER_LOG="${BASE}/${SERVER_EXE}.log"
|
SERVER_LOG="${BASE}/${SERVER_EXE}.log"
|
||||||
|
|
||||||
HEX="deadbeef1234deadbeef1234deadbeef1234aaaa"
|
HEX="deadbeef1234deadbeef1234deadbeef1234aaaa"
|
||||||
${SERVER_EXE} init ${HEX} --home="$SERVER" >> "$SERVER_LOG"
|
${SERVER_EXE} init ${HEX} --home="$SERVER" >> "$SERVER_LOG"
|
||||||
if ! assertTrue $?; then return 1; fi
|
if ! assertTrue "line=${LINENO}" $?; then return 1; fi
|
||||||
|
|
||||||
GENESIS_FILE=${SERVER}/genesis.json
|
GENESIS_FILE=${SERVER}/genesis.json
|
||||||
CHAIN_ID=$(cat ${GENESIS_FILE} | jq .chain_id | tr -d \")
|
CHAIN_ID=$(cat ${GENESIS_FILE} | jq .chain_id | tr -d \")
|
||||||
|
|
||||||
printf "starting ${SERVER_EXE}...\n"
|
printf "starting ${SERVER_EXE}...\n"
|
||||||
${SERVER_EXE} start --home="$SERVER" >> "$SERVER_LOG" 2>&1 &
|
${SERVER_EXE} start --home="$SERVER" >> "$SERVER_LOG" 2>&1 &
|
||||||
sleep 5
|
sleep 5
|
||||||
PID_SERVER=$!
|
PID_SERVER=$!
|
||||||
disown
|
disown
|
||||||
if ! ps $PID_SERVER >/dev/null; then
|
if ! ps $PID_SERVER >/dev/null; then
|
||||||
echo "**STARTUP FAILED**"
|
echo "**STARTUP FAILED**"
|
||||||
cat $SERVER_LOG
|
cat $SERVER_LOG
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
oneTimeTearDown() {
|
oneTimeTearDown() {
|
||||||
printf "\nstopping ${SERVER_EXE}..."
|
printf "\nstopping ${SERVER_EXE}..."
|
||||||
kill -9 $PID_SERVER >/dev/null 2>&1
|
kill -9 $PID_SERVER >/dev/null 2>&1
|
||||||
sleep 1
|
sleep 1
|
||||||
}
|
}
|
||||||
|
|
||||||
test01goodInit() {
|
test01goodInit() {
|
||||||
export BCHOME=${BASE}/client-01
|
export BCHOME=${BASE}/client-01
|
||||||
assertFalse "ls ${BCHOME} 2>/dev/null >&2"
|
assertFalse "line=${LINENO}" "ls ${BCHOME} 2>/dev/null >&2"
|
||||||
|
|
||||||
echo y | ${CLIENT_EXE} init --node=tcp://localhost:46657 --chain-id="${CHAIN_ID}" > /dev/null
|
echo y | ${CLIENT_EXE} init --node=tcp://localhost:46657 --chain-id="${CHAIN_ID}" > /dev/null
|
||||||
assertTrue "initialized light-client" $?
|
assertTrue "line=${LINENO}, initialized light-client" $?
|
||||||
checkDir $BCHOME 3
|
checkDir $BCHOME 3
|
||||||
}
|
}
|
||||||
|
|
||||||
test02badInit() {
|
test02badInit() {
|
||||||
export BCHOME=${BASE}/client-02
|
export BCHOME=${BASE}/client-02
|
||||||
assertFalse "ls ${BCHOME} 2>/dev/null >&2"
|
assertFalse "line=${LINENO}" "ls ${BCHOME} 2>/dev/null >&2"
|
||||||
|
|
||||||
# no node where we go
|
# no node where we go
|
||||||
echo y | ${CLIENT_EXE} init --node=tcp://localhost:9999 --chain-id="${CHAIN_ID}" > /dev/null 2>&1
|
echo y | ${CLIENT_EXE} init --node=tcp://localhost:9999 --chain-id="${CHAIN_ID}" > /dev/null 2>&1
|
||||||
assertFalse "invalid init" $?
|
assertFalse "line=${LINENO}, invalid init" $?
|
||||||
# dir there, but empty...
|
# dir there, but empty...
|
||||||
checkDir $BCHOME 0
|
checkDir $BCHOME 0
|
||||||
|
|
||||||
# try with invalid chain id
|
# try with invalid chain id
|
||||||
echo y | ${CLIENT_EXE} init --node=tcp://localhost:46657 --chain-id="bad-chain-id" > /dev/null 2>&1
|
echo y | ${CLIENT_EXE} init --node=tcp://localhost:46657 --chain-id="bad-chain-id" > /dev/null 2>&1
|
||||||
assertFalse "invalid init" $?
|
assertFalse "line=${LINENO}, invalid init" $?
|
||||||
checkDir $BCHOME 0
|
checkDir $BCHOME 0
|
||||||
|
|
||||||
# reject the response
|
# reject the response
|
||||||
echo n | ${CLIENT_EXE} init --node=tcp://localhost:46657 --chain-id="${CHAIN_ID}" > /dev/null 2>&1
|
echo n | ${CLIENT_EXE} init --node=tcp://localhost:46657 --chain-id="${CHAIN_ID}" > /dev/null 2>&1
|
||||||
assertFalse "invalid init" $?
|
assertFalse "line=${LINENO}, invalid init" $?
|
||||||
checkDir $BCHOME 0
|
checkDir $BCHOME 0
|
||||||
}
|
}
|
||||||
|
|
||||||
test03noDoubleInit() {
|
test03noDoubleInit() {
|
||||||
export BCHOME=${BASE}/client-03
|
export BCHOME=${BASE}/client-03
|
||||||
assertFalse "ls ${BCHOME} 2>/dev/null >&2"
|
assertFalse "line=${LINENO}" "ls ${BCHOME} 2>/dev/null >&2"
|
||||||
|
|
||||||
# init properly
|
# init properly
|
||||||
echo y | ${CLIENT_EXE} init --node=tcp://localhost:46657 --chain-id="${CHAIN_ID}" > /dev/null 2>&1
|
echo y | ${CLIENT_EXE} init --node=tcp://localhost:46657 --chain-id="${CHAIN_ID}" > /dev/null 2>&1
|
||||||
assertTrue "initialized light-client" $?
|
assertTrue "line=${LINENO}, initialized light-client" $?
|
||||||
checkDir $BCHOME 3
|
checkDir $BCHOME 3
|
||||||
|
|
||||||
# try again, and we get an error
|
# try again, and we get an error
|
||||||
echo y | ${CLIENT_EXE} init --node=tcp://localhost:46657 --chain-id="${CHAIN_ID}" > /dev/null 2>&1
|
echo y | ${CLIENT_EXE} init --node=tcp://localhost:46657 --chain-id="${CHAIN_ID}" > /dev/null 2>&1
|
||||||
assertFalse "warning on re-init" $?
|
assertFalse "line=${LINENO}, warning on re-init" $?
|
||||||
checkDir $BCHOME 3
|
checkDir $BCHOME 3
|
||||||
|
|
||||||
# unless we --force-reset
|
# unless we --force-reset
|
||||||
echo y | ${CLIENT_EXE} init --force-reset --node=tcp://localhost:46657 --chain-id="${CHAIN_ID}" > /dev/null 2>&1
|
echo y | ${CLIENT_EXE} init --force-reset --node=tcp://localhost:46657 --chain-id="${CHAIN_ID}" > /dev/null 2>&1
|
||||||
assertTrue "re-initialized light-client" $?
|
assertTrue "line=${LINENO}, re-initialized light-client" $?
|
||||||
checkDir $BCHOME 3
|
checkDir $BCHOME 3
|
||||||
}
|
}
|
||||||
|
|
||||||
test04acceptGenesisFile() {
|
test04acceptGenesisFile() {
|
||||||
export BCHOME=${BASE}/client-04
|
export BCHOME=${BASE}/client-04
|
||||||
assertFalse "ls ${BCHOME} 2>/dev/null >&2"
|
assertFalse "line=${LINENO}" "ls ${BCHOME} 2>/dev/null >&2"
|
||||||
|
|
||||||
# init properly
|
# init properly
|
||||||
${CLIENT_EXE} init --node=tcp://localhost:46657 --genesis=${GENESIS_FILE} > /dev/null 2>&1
|
${CLIENT_EXE} init --node=tcp://localhost:46657 --genesis=${GENESIS_FILE} > /dev/null 2>&1
|
||||||
assertTrue "initialized light-client" $?
|
assertTrue "line=${LINENO}, initialized light-client" $?
|
||||||
checkDir $BCHOME 3
|
checkDir $BCHOME 3
|
||||||
}
|
}
|
||||||
|
|
||||||
# XXX Ex: checkDir $DIR $FILES
|
# XXX Ex: checkDir $DIR $FILES
|
||||||
# Makes sure directory exists and has the given number of files
|
# Makes sure directory exists and has the given number of files
|
||||||
checkDir() {
|
checkDir() {
|
||||||
assertTrue "ls ${1} 2>/dev/null >&2"
|
assertTrue "line=${LINENO}" "ls ${1} 2>/dev/null >&2"
|
||||||
assertEquals "no files created" "$2" $(ls $1 | wc -l)
|
assertEquals "line=${LINENO}, no files created" "$2" $(ls $1 | wc -l)
|
||||||
}
|
}
|
||||||
|
|
||||||
# load and run these tests with shunit2!
|
# load and run these tests with shunit2!
|
||||||
|
|
|
@ -4,24 +4,24 @@ CLIENT_EXE=basecli
|
||||||
|
|
||||||
|
|
||||||
oneTimeSetUp() {
|
oneTimeSetUp() {
|
||||||
PASS=qwertyuiop
|
PASS=qwertyuiop
|
||||||
export BCHOME=$HOME/.bc_keys_test
|
export BCHOME=$HOME/.bc_keys_test
|
||||||
${CLIENT_EXE} reset_all
|
${CLIENT_EXE} reset_all
|
||||||
assertTrue $?
|
assertTrue "line ${LINENO}" $?
|
||||||
}
|
}
|
||||||
|
|
||||||
newKey(){
|
newKey(){
|
||||||
assertNotNull "keyname required" "$1"
|
assertNotNull "keyname required" "$1"
|
||||||
KEYPASS=${2:-qwertyuiop}
|
KEYPASS=${2:-qwertyuiop}
|
||||||
echo $KEYPASS | ${CLIENT_EXE} keys new $1 >/dev/null 2>&1
|
echo $KEYPASS | ${CLIENT_EXE} keys new $1 >/dev/null 2>&1
|
||||||
assertTrue "created $1" $?
|
assertTrue "line ${LINENO}, created $1" $?
|
||||||
}
|
}
|
||||||
|
|
||||||
testMakeKeys() {
|
testMakeKeys() {
|
||||||
USER=demouser
|
USER=demouser
|
||||||
assertFalse "already user $USER" "${CLIENT_EXE} keys get $USER"
|
assertFalse "line ${LINENO}, already user $USER" "${CLIENT_EXE} keys get $USER"
|
||||||
newKey $USER
|
newKey $USER
|
||||||
assertTrue "no user $USER" "${CLIENT_EXE} keys get $USER"
|
assertTrue "line ${LINENO}, no user $USER" "${CLIENT_EXE} keys get $USER"
|
||||||
}
|
}
|
||||||
|
|
||||||
# load and run these tests with shunit2!
|
# load and run these tests with shunit2!
|
||||||
|
|
192
tests/cli/rpc.sh
192
tests/cli/rpc.sh
|
@ -4,125 +4,125 @@ CLIENT_EXE=basecli
|
||||||
SERVER_EXE=basecoin
|
SERVER_EXE=basecoin
|
||||||
|
|
||||||
oneTimeSetUp() {
|
oneTimeSetUp() {
|
||||||
BASE=~/.bc_init_test
|
BASE=~/.bc_init_test
|
||||||
rm -rf "$BASE"
|
rm -rf "$BASE"
|
||||||
mkdir -p "$BASE"
|
mkdir -p "$BASE"
|
||||||
|
|
||||||
SERVER="${BASE}/server"
|
SERVER="${BASE}/server"
|
||||||
SERVER_LOG="${BASE}/${SERVER_EXE}.log"
|
SERVER_LOG="${BASE}/${SERVER_EXE}.log"
|
||||||
|
|
||||||
HEX="deadbeef1234deadbeef1234deadbeef1234aaaa"
|
HEX="deadbeef1234deadbeef1234deadbeef1234aaaa"
|
||||||
${SERVER_EXE} init ${HEX} --home="$SERVER" >> "$SERVER_LOG"
|
${SERVER_EXE} init ${HEX} --home="$SERVER" >> "$SERVER_LOG"
|
||||||
if ! assertTrue $?; then return 1; fi
|
if ! assertTrue "line=${LINENO}" $?; then return 1; fi
|
||||||
|
|
||||||
GENESIS_FILE=${SERVER}/genesis.json
|
GENESIS_FILE=${SERVER}/genesis.json
|
||||||
CHAIN_ID=$(cat ${GENESIS_FILE} | jq .chain_id | tr -d \")
|
CHAIN_ID=$(cat ${GENESIS_FILE} | jq .chain_id | tr -d \")
|
||||||
|
|
||||||
printf "starting ${SERVER_EXE}...\n"
|
printf "starting ${SERVER_EXE}...\n"
|
||||||
${SERVER_EXE} start --home="$SERVER" >> "$SERVER_LOG" 2>&1 &
|
${SERVER_EXE} start --home="$SERVER" >> "$SERVER_LOG" 2>&1 &
|
||||||
sleep 5
|
sleep 5
|
||||||
PID_SERVER=$!
|
PID_SERVER=$!
|
||||||
disown
|
disown
|
||||||
if ! ps $PID_SERVER >/dev/null; then
|
if ! ps $PID_SERVER >/dev/null; then
|
||||||
echo "**STARTUP FAILED**"
|
echo "**STARTUP FAILED**"
|
||||||
cat $SERVER_LOG
|
cat $SERVER_LOG
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# this sets the base for all client queries in the tests
|
# this sets the base for all client queries in the tests
|
||||||
export BCHOME=${BASE}/client
|
export BCHOME=${BASE}/client
|
||||||
${CLIENT_EXE} init --node=tcp://localhost:46657 --genesis=${GENESIS_FILE} > /dev/null 2>&1
|
${CLIENT_EXE} init --node=tcp://localhost:46657 --genesis=${GENESIS_FILE} > /dev/null 2>&1
|
||||||
if ! assertTrue "initialized light-client" "$?"; then
|
if ! assertTrue "line=${LINENO}, initialized light-client" "$?"; then
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
oneTimeTearDown() {
|
oneTimeTearDown() {
|
||||||
printf "\nstopping ${SERVER_EXE}..."
|
printf "\nstopping ${SERVER_EXE}..."
|
||||||
kill -9 $PID_SERVER >/dev/null 2>&1
|
kill -9 $PID_SERVER >/dev/null 2>&1
|
||||||
sleep 1
|
sleep 1
|
||||||
}
|
}
|
||||||
|
|
||||||
test01getInsecure() {
|
test01GetInsecure() {
|
||||||
GENESIS=$(${CLIENT_EXE} rpc genesis)
|
GENESIS=$(${CLIENT_EXE} rpc genesis)
|
||||||
assertTrue "get genesis" "$?"
|
assertTrue "line=${LINENO}, get genesis" "$?"
|
||||||
MYCHAIN=$(echo ${GENESIS} | jq .genesis.chain_id | tr -d \")
|
MYCHAIN=$(echo ${GENESIS} | jq .genesis.chain_id | tr -d \")
|
||||||
assertEquals "genesis chain matches" "${CHAIN_ID}" "${MYCHAIN}"
|
assertEquals "line=${LINENO}, genesis chain matches" "${CHAIN_ID}" "${MYCHAIN}"
|
||||||
|
|
||||||
STATUS=$(${CLIENT_EXE} rpc status)
|
STATUS=$(${CLIENT_EXE} rpc status)
|
||||||
assertTrue "get status" "$?"
|
assertTrue "line=${LINENO}, get status" "$?"
|
||||||
SHEIGHT=$(echo ${STATUS} | jq .latest_block_height)
|
SHEIGHT=$(echo ${STATUS} | jq .latest_block_height)
|
||||||
assertTrue "parsed status" "$?"
|
assertTrue "line=${LINENO}, parsed status" "$?"
|
||||||
assertNotNull "has a height" "${SHEIGHT}"
|
assertNotNull "line=${LINENO}, has a height" "${SHEIGHT}"
|
||||||
|
|
||||||
VALS=$(${CLIENT_EXE} rpc validators)
|
VALS=$(${CLIENT_EXE} rpc validators)
|
||||||
assertTrue "get validators" "$?"
|
assertTrue "line=${LINENO}, get validators" "$?"
|
||||||
VHEIGHT=$(echo ${VALS} | jq .block_height)
|
VHEIGHT=$(echo ${VALS} | jq .block_height)
|
||||||
assertTrue "parsed validators" "$?"
|
assertTrue "line=${LINENO}, parsed validators" "$?"
|
||||||
assertTrue "sensible heights: $SHEIGHT / $VHEIGHT" "test $VHEIGHT -ge $SHEIGHT"
|
assertTrue "line=${LINENO}, sensible heights: $SHEIGHT / $VHEIGHT" "test $VHEIGHT -ge $SHEIGHT"
|
||||||
VCNT=$(echo ${VALS} | jq '.validators | length')
|
VCNT=$(echo ${VALS} | jq '.validators | length')
|
||||||
assertEquals "one validator" "1" "$VCNT"
|
assertEquals "line=${LINENO}, one validator" "1" "$VCNT"
|
||||||
|
|
||||||
INFO=$(${CLIENT_EXE} rpc info)
|
INFO=$(${CLIENT_EXE} rpc info)
|
||||||
assertTrue "get info" "$?"
|
assertTrue "line=${LINENO}, get info" "$?"
|
||||||
DATA=$(echo $INFO | jq .response.data)
|
DATA=$(echo $INFO | jq .response.data)
|
||||||
assertEquals "basecoin info" '"Basecoin v0.6.1"' "$DATA"
|
assertEquals "line=${LINENO}, basecoin info" '"Basecoin v0.6.1"' "$DATA"
|
||||||
}
|
}
|
||||||
|
|
||||||
test02getSecure() {
|
test02GetSecure() {
|
||||||
HEIGHT=$(${CLIENT_EXE} rpc status | jq .latest_block_height)
|
HEIGHT=$(${CLIENT_EXE} rpc status | jq .latest_block_height)
|
||||||
assertTrue "get status" "$?"
|
assertTrue "line=${LINENO}, get status" "$?"
|
||||||
|
|
||||||
# check block produces something reasonable
|
# check block produces something reasonable
|
||||||
assertFalse "missing height" "${CLIENT_EXE} rpc block"
|
assertFalse "line=${LINENO}, missing height" "${CLIENT_EXE} rpc block"
|
||||||
BLOCK=$(${CLIENT_EXE} rpc block --height=$HEIGHT)
|
BLOCK=$(${CLIENT_EXE} rpc block --height=$HEIGHT)
|
||||||
assertTrue "get block" "$?"
|
assertTrue "line=${LINENO}, get block" "$?"
|
||||||
MHEIGHT=$(echo $BLOCK | jq .block_meta.header.height)
|
MHEIGHT=$(echo $BLOCK | jq .block_meta.header.height)
|
||||||
assertEquals "meta height" "${HEIGHT}" "${MHEIGHT}"
|
assertEquals "line=${LINENO}, meta height" "${HEIGHT}" "${MHEIGHT}"
|
||||||
BHEIGHT=$(echo $BLOCK | jq .block.header.height)
|
BHEIGHT=$(echo $BLOCK | jq .block.header.height)
|
||||||
assertEquals "meta height" "${HEIGHT}" "${BHEIGHT}"
|
assertEquals "line=${LINENO}, meta height" "${HEIGHT}" "${BHEIGHT}"
|
||||||
|
|
||||||
# check commit produces something reasonable
|
# check commit produces something reasonable
|
||||||
assertFalse "missing height" "${CLIENT_EXE} rpc commit"
|
assertFalse "line=${LINENO}, missing height" "${CLIENT_EXE} rpc commit"
|
||||||
let "CHEIGHT = $HEIGHT - 1"
|
let "CHEIGHT = $HEIGHT - 1"
|
||||||
COMMIT=$(${CLIENT_EXE} rpc commit --height=$CHEIGHT)
|
COMMIT=$(${CLIENT_EXE} rpc commit --height=$CHEIGHT)
|
||||||
assertTrue "get commit" "$?"
|
assertTrue "line=${LINENO}, get commit" "$?"
|
||||||
HHEIGHT=$(echo $COMMIT | jq .header.height)
|
HHEIGHT=$(echo $COMMIT | jq .header.height)
|
||||||
assertEquals "commit height" "${CHEIGHT}" "${HHEIGHT}"
|
assertEquals "line=${LINENO}, commit height" "${CHEIGHT}" "${HHEIGHT}"
|
||||||
assertEquals "canonical" "true" $(echo $COMMIT | jq .canonical)
|
assertEquals "line=${LINENO}, canonical" "true" $(echo $COMMIT | jq .canonical)
|
||||||
BSIG=$(echo $BLOCK | jq .block.last_commit)
|
BSIG=$(echo $BLOCK | jq .block.last_commit)
|
||||||
CSIG=$(echo $COMMIT | jq .commit)
|
CSIG=$(echo $COMMIT | jq .commit)
|
||||||
assertEquals "block and commit" "$BSIG" "$CSIG"
|
assertEquals "line=${LINENO}, block and commit" "$BSIG" "$CSIG"
|
||||||
|
|
||||||
# now let's get some headers
|
# now let's get some headers
|
||||||
# assertFalse "missing height" "${CLIENT_EXE} rpc headers"
|
# assertFalse "missing height" "${CLIENT_EXE} rpc headers"
|
||||||
HEADERS=$(${CLIENT_EXE} rpc headers --min=$CHEIGHT --max=$HEIGHT)
|
HEADERS=$(${CLIENT_EXE} rpc headers --min=$CHEIGHT --max=$HEIGHT)
|
||||||
assertTrue "get headers" "$?"
|
assertTrue "line=${LINENO}, get headers" "$?"
|
||||||
assertEquals "proper height" "$HEIGHT" $(echo $HEADERS | jq '.last_height')
|
assertEquals "line=${LINENO}, proper height" "$HEIGHT" $(echo $HEADERS | jq '.last_height')
|
||||||
assertEquals "two headers" "2" $(echo $HEADERS | jq '.block_metas | length')
|
assertEquals "line=${LINENO}, two headers" "2" $(echo $HEADERS | jq '.block_metas | length')
|
||||||
# should we check these headers?
|
# should we check these headers?
|
||||||
CHEAD=$(echo $COMMIT | jq .header)
|
CHEAD=$(echo $COMMIT | jq .header)
|
||||||
# most recent first, so the commit header is second....
|
# most recent first, so the commit header is second....
|
||||||
HHEAD=$(echo $HEADERS | jq .block_metas[1].header)
|
HHEAD=$(echo $HEADERS | jq .block_metas[1].header)
|
||||||
assertEquals "commit and header" "$CHEAD" "$HHEAD"
|
assertEquals "line=${LINENO}, commit and header" "$CHEAD" "$HHEAD"
|
||||||
}
|
}
|
||||||
|
|
||||||
test03waiting() {
|
test03Waiting() {
|
||||||
START=$(${CLIENT_EXE} rpc status | jq .latest_block_height)
|
START=$(${CLIENT_EXE} rpc status | jq .latest_block_height)
|
||||||
assertTrue "get status" "$?"
|
assertTrue "line=${LINENO}, get status" "$?"
|
||||||
|
|
||||||
let "NEXT = $START + 5"
|
let "NEXT = $START + 5"
|
||||||
assertFalse "no args" "${CLIENT_EXE} rpc wait"
|
assertFalse "line=${LINENO}, no args" "${CLIENT_EXE} rpc wait"
|
||||||
assertFalse "too long" "${CLIENT_EXE} rpc wait --height=1234"
|
assertFalse "line=${LINENO}, too long" "${CLIENT_EXE} rpc wait --height=1234"
|
||||||
assertTrue "normal wait" "${CLIENT_EXE} rpc wait --height=$NEXT"
|
assertTrue "line=${LINENO}, normal wait" "${CLIENT_EXE} rpc wait --height=$NEXT"
|
||||||
|
|
||||||
STEP=$(${CLIENT_EXE} rpc status | jq .latest_block_height)
|
STEP=$(${CLIENT_EXE} rpc status | jq .latest_block_height)
|
||||||
assertEquals "wait until height" "$NEXT" "$STEP"
|
assertEquals "line=${LINENO}, wait until height" "$NEXT" "$STEP"
|
||||||
|
|
||||||
let "NEXT = $STEP + 3"
|
let "NEXT = $STEP + 3"
|
||||||
assertTrue "${CLIENT_EXE} rpc wait --delta=3"
|
assertTrue "line=${LINENO}, ${CLIENT_EXE} rpc wait --delta=3"
|
||||||
STEP=$(${CLIENT_EXE} rpc status | jq .latest_block_height)
|
STEP=$(${CLIENT_EXE} rpc status | jq .latest_block_height)
|
||||||
assertEquals "wait for delta" "$NEXT" "$STEP"
|
assertEquals "line=${LINENO}, wait for delta" "$NEXT" "$STEP"
|
||||||
}
|
}
|
||||||
|
|
||||||
# load and run these tests with shunit2!
|
# load and run these tests with shunit2!
|
||||||
|
|
Loading…
Reference in New Issue