diff --git a/gaia/cli_test/README.md b/gaia/cli_test/README.md deleted file mode 100644 index 37fd41ce..00000000 --- a/gaia/cli_test/README.md +++ /dev/null @@ -1,51 +0,0 @@ -# Gaia CLI Integration tests - -The gaia cli integration tests live in this folder. You can run the full suite by running: - -```bash -$ go test -v -p 4 ./cmd/gaia/cli_test/... -# OR! -$ make test_cli -``` -> NOTE: While the full suite runs in parallel, some of the tests can take up to a minute to complete - -### Test Structure - -This integration suite [uses a thin wrapper](https://godoc.org/github.com/cosmos/cosmos-sdk/tests) over the [`os/exec`](https://golang.org/pkg/os/exec/) package. This allows the integration test to run against built binaries (both `gaiad` and `gaiacli` are used) while being written in golang. This allows tests to take advantage of the various golang code we have for operations like marshal/unmarshal, crypto, etc... - -> NOTE: The tests will use whatever `gaiad` or `gaiacli` binaries are available in your `$PATH`. You can check which binary will be run by the suite by running `which gaiad` or `which gaiacli`. If you have your `$GOPATH` properly setup they should be in `$GOPATH/bin/gaia*`. This will ensure that your test uses the latest binary you have built - -Tests generally follow this structure: - -```go -func TestMyNewCommand(t *testing.T) { - t.Parallel() - f := InitFixtures(t) - - // start gaiad server - proc := f.GDStart() - defer proc.Stop(false) - - // Your test code goes here... - - f.Cleanup() -} -``` - -This boilerplate above: -- Ensures the tests run in parallel. Because the tests are calling out to `os/exec` for many operations these tests can take a long time to run. -- Creates `.gaiad` and `.gaiacli` folders in a new temp folder. -- Uses `gaiacli` to create 2 accounts for use in testing: `foo` and `bar` -- Creates a genesis file with coins (`1000footoken,1000feetoken,150stake`) controlled by the `foo` key -- Generates an initial bonding transaction (`gentx`) to make the `foo` key a validator at genesis -- Starts `gaiad` and stops it once the test exits -- Cleans up test state on a successful run - -### Notes when adding/running tests - -- Because the tests run against a built binary, you should make sure you build every time the code changes and you want to test again, otherwise you will be testing against an older version. If you are adding new tests this can easily lead to confusing test results. -- The [`test_helpers.go`](./test_helpers.go) file is organized according to the format of `gaiacli` and `gaiad` commands. There are comments with section headers describing the different areas. Helper functions to call CLI functionality are generally named after the command (e.g. `gaiacli query staking validator` would be `QueryStakingValidator`). Try to keep functions grouped by their position in the command tree. -- Test state that is needed by `tx` and `query` commands (`home`, `chain_id`, etc...) is stored on the `Fixtures` object. This makes constructing your new tests almost trivial. -- Sometimes if you exit a test early there can be still running `gaiad` and `gaiacli` processes that will interrupt subsequent runs. Still running `gaiacli` processes will block access to the keybase while still running `gaiad` processes will block ports and prevent new tests from spinning up. You can ensure new tests spin up clean by running `pkill -9 gaiad && pkill -9 gaiacli` before each test run. -- Most `query` and `tx` commands take a variadic `flags` argument. This pattern allows for the creation of a general function which is easily modified by adding flags. See the `TxSend` function and its use for a good example. -- `Tx*` functions follow a general pattern and return `(success bool, stdout string, stderr string)`. This allows for easy testing of multiple different flag configurations. See `TestGaiaCLICreateValidator` or `TestGaiaCLISubmitProposal` for a good example of the pattern. diff --git a/gaia/cli_test/cli_test.go b/gaia/cli_test/cli_test.go deleted file mode 100644 index 8a36a390..00000000 --- a/gaia/cli_test/cli_test.go +++ /dev/null @@ -1,1093 +0,0 @@ -// +build cli_test - -package clitest - -import ( - "encoding/base64" - "errors" - "fmt" - "io/ioutil" - "os" - "path" - "path/filepath" - "strings" - "testing" - "time" - - "github.com/tendermint/tendermint/crypto/ed25519" - - "github.com/stretchr/testify/require" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/cmd/gaia/app" - "github.com/cosmos/cosmos-sdk/tests" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/cosmos/cosmos-sdk/x/gov" -) - -func TestGaiaCLIKeysAddMultisig(t *testing.T) { - t.Parallel() - f := InitFixtures(t) - - // key names order does not matter - f.KeysAdd("msig1", "--multisig-threshold=2", - fmt.Sprintf("--multisig=%s,%s", keyBar, keyBaz)) - f.KeysAdd("msig2", "--multisig-threshold=2", - fmt.Sprintf("--multisig=%s,%s", keyBaz, keyBar)) - require.Equal(t, f.KeysShow("msig1").Address, f.KeysShow("msig2").Address) - - f.KeysAdd("msig3", "--multisig-threshold=2", - fmt.Sprintf("--multisig=%s,%s", keyBar, keyBaz), - "--nosort") - f.KeysAdd("msig4", "--multisig-threshold=2", - fmt.Sprintf("--multisig=%s,%s", keyBaz, keyBar), - "--nosort") - require.NotEqual(t, f.KeysShow("msig3").Address, f.KeysShow("msig4").Address) -} - -func TestGaiaCLIKeysAddRecover(t *testing.T) { - t.Parallel() - f := InitFixtures(t) - - exitSuccess, _, _ := f.KeysAddRecover("empty-mnemonic", "") - require.False(t, exitSuccess) - - exitSuccess, _, _ = f.KeysAddRecover("test-recover", "dentist task convince chimney quality leave banana trade firm crawl eternal easily") - require.True(t, exitSuccess) - require.Equal(t, "cosmos1qcfdf69js922qrdr4yaww3ax7gjml6pdds46f4", f.KeyAddress("test-recover").String()) -} - -func TestGaiaCLIKeysAddRecoverHDPath(t *testing.T) { - t.Parallel() - f := InitFixtures(t) - - f.KeysAddRecoverHDPath("test-recoverHD1", "dentist task convince chimney quality leave banana trade firm crawl eternal easily", 0, 0) - require.Equal(t, "cosmos1qcfdf69js922qrdr4yaww3ax7gjml6pdds46f4", f.KeyAddress("test-recoverHD1").String()) - - f.KeysAddRecoverHDPath("test-recoverH2", "dentist task convince chimney quality leave banana trade firm crawl eternal easily", 1, 5) - require.Equal(t, "cosmos1pdfav2cjhry9k79nu6r8kgknnjtq6a7rykmafy", f.KeyAddress("test-recoverH2").String()) - - f.KeysAddRecoverHDPath("test-recoverH3", "dentist task convince chimney quality leave banana trade firm crawl eternal easily", 1, 17) - require.Equal(t, "cosmos1909k354n6wl8ujzu6kmh49w4d02ax7qvlkv4sn", f.KeyAddress("test-recoverH3").String()) - - f.KeysAddRecoverHDPath("test-recoverH4", "dentist task convince chimney quality leave banana trade firm crawl eternal easily", 2, 17) - require.Equal(t, "cosmos1v9plmhvyhgxk3th9ydacm7j4z357s3nhtwsjat", f.KeyAddress("test-recoverH4").String()) -} - -func TestGaiaCLIMinimumFees(t *testing.T) { - t.Parallel() - f := InitFixtures(t) - - // start gaiad server with minimum fees - minGasPrice, _ := sdk.NewDecFromStr("0.000006") - fees := fmt.Sprintf( - "--minimum-gas-prices=%s,%s", - sdk.NewDecCoinFromDec(feeDenom, minGasPrice), - sdk.NewDecCoinFromDec(fee2Denom, minGasPrice), - ) - proc := f.GDStart(fees) - defer proc.Stop(false) - - barAddr := f.KeyAddress(keyBar) - - // Send a transaction that will get rejected - success, _, _ := f.TxSend(keyFoo, barAddr, sdk.NewInt64Coin(fee2Denom, 10), "-y") - require.False(f.T, success) - tests.WaitForNextNBlocksTM(1, f.Port) - - // Ensure tx w/ correct fees pass - txFees := fmt.Sprintf("--fees=%s", sdk.NewInt64Coin(feeDenom, 2)) - success, _, _ = f.TxSend(keyFoo, barAddr, sdk.NewInt64Coin(fee2Denom, 10), txFees, "-y") - require.True(f.T, success) - tests.WaitForNextNBlocksTM(1, f.Port) - - // Ensure tx w/ improper fees fails - txFees = fmt.Sprintf("--fees=%s", sdk.NewInt64Coin(feeDenom, 1)) - success, _, _ = f.TxSend(keyFoo, barAddr, sdk.NewInt64Coin(fooDenom, 10), txFees, "-y") - require.False(f.T, success) - - // Cleanup testing directories - f.Cleanup() -} - -func TestGaiaCLIGasPrices(t *testing.T) { - t.Parallel() - f := InitFixtures(t) - - // start gaiad server with minimum fees - minGasPrice, _ := sdk.NewDecFromStr("0.000006") - proc := f.GDStart(fmt.Sprintf("--minimum-gas-prices=%s", sdk.NewDecCoinFromDec(feeDenom, minGasPrice))) - defer proc.Stop(false) - - barAddr := f.KeyAddress(keyBar) - - // insufficient gas prices (tx fails) - badGasPrice, _ := sdk.NewDecFromStr("0.000003") - success, _, _ := f.TxSend( - keyFoo, barAddr, sdk.NewInt64Coin(fooDenom, 50), - fmt.Sprintf("--gas-prices=%s", sdk.NewDecCoinFromDec(feeDenom, badGasPrice)), "-y") - require.False(t, success) - - // wait for a block confirmation - tests.WaitForNextNBlocksTM(1, f.Port) - - // sufficient gas prices (tx passes) - success, _, _ = f.TxSend( - keyFoo, barAddr, sdk.NewInt64Coin(fooDenom, 50), - fmt.Sprintf("--gas-prices=%s", sdk.NewDecCoinFromDec(feeDenom, minGasPrice)), "-y") - require.True(t, success) - - // wait for a block confirmation - tests.WaitForNextNBlocksTM(1, f.Port) - - f.Cleanup() -} - -func TestGaiaCLIFeesDeduction(t *testing.T) { - t.Parallel() - f := InitFixtures(t) - - // start gaiad server with minimum fees - minGasPrice, _ := sdk.NewDecFromStr("0.000006") - proc := f.GDStart(fmt.Sprintf("--minimum-gas-prices=%s", sdk.NewDecCoinFromDec(feeDenom, minGasPrice))) - defer proc.Stop(false) - - // Save key addresses for later use - fooAddr := f.KeyAddress(keyFoo) - barAddr := f.KeyAddress(keyBar) - - fooAcc := f.QueryAccount(fooAddr) - fooAmt := fooAcc.GetCoins().AmountOf(fooDenom) - - // test simulation - success, _, _ := f.TxSend( - keyFoo, barAddr, sdk.NewInt64Coin(fooDenom, 1000), - fmt.Sprintf("--fees=%s", sdk.NewInt64Coin(feeDenom, 2)), "--dry-run") - require.True(t, success) - - // Wait for a block - tests.WaitForNextNBlocksTM(1, f.Port) - - // ensure state didn't change - fooAcc = f.QueryAccount(fooAddr) - require.Equal(t, fooAmt.Int64(), fooAcc.GetCoins().AmountOf(fooDenom).Int64()) - - // insufficient funds (coins + fees) tx fails - largeCoins := sdk.TokensFromTendermintPower(10000000) - success, _, _ = f.TxSend( - keyFoo, barAddr, sdk.NewCoin(fooDenom, largeCoins), - fmt.Sprintf("--fees=%s", sdk.NewInt64Coin(feeDenom, 2)), "-y") - require.False(t, success) - - // Wait for a block - tests.WaitForNextNBlocksTM(1, f.Port) - - // ensure state didn't change - fooAcc = f.QueryAccount(fooAddr) - require.Equal(t, fooAmt.Int64(), fooAcc.GetCoins().AmountOf(fooDenom).Int64()) - - // test success (transfer = coins + fees) - success, _, _ = f.TxSend( - keyFoo, barAddr, sdk.NewInt64Coin(fooDenom, 500), - fmt.Sprintf("--fees=%s", sdk.NewInt64Coin(feeDenom, 2)), "-y") - require.True(t, success) - - f.Cleanup() -} - -func TestGaiaCLISend(t *testing.T) { - t.Parallel() - f := InitFixtures(t) - - // start gaiad server - proc := f.GDStart() - defer proc.Stop(false) - - // Save key addresses for later use - fooAddr := f.KeyAddress(keyFoo) - barAddr := f.KeyAddress(keyBar) - - fooAcc := f.QueryAccount(fooAddr) - startTokens := sdk.TokensFromTendermintPower(50) - require.Equal(t, startTokens, fooAcc.GetCoins().AmountOf(denom)) - - // Send some tokens from one account to the other - sendTokens := sdk.TokensFromTendermintPower(10) - f.TxSend(keyFoo, barAddr, sdk.NewCoin(denom, sendTokens), "-y") - tests.WaitForNextNBlocksTM(1, f.Port) - - // Ensure account balances match expected - barAcc := f.QueryAccount(barAddr) - require.Equal(t, sendTokens, barAcc.GetCoins().AmountOf(denom)) - fooAcc = f.QueryAccount(fooAddr) - require.Equal(t, startTokens.Sub(sendTokens), fooAcc.GetCoins().AmountOf(denom)) - - // Test --dry-run - success, _, _ := f.TxSend(keyFoo, barAddr, sdk.NewCoin(denom, sendTokens), "--dry-run") - require.True(t, success) - - // Check state didn't change - fooAcc = f.QueryAccount(fooAddr) - require.Equal(t, startTokens.Sub(sendTokens), fooAcc.GetCoins().AmountOf(denom)) - - // test autosequencing - f.TxSend(keyFoo, barAddr, sdk.NewCoin(denom, sendTokens), "-y") - tests.WaitForNextNBlocksTM(1, f.Port) - - // Ensure account balances match expected - barAcc = f.QueryAccount(barAddr) - require.Equal(t, sendTokens.MulRaw(2), barAcc.GetCoins().AmountOf(denom)) - fooAcc = f.QueryAccount(fooAddr) - require.Equal(t, startTokens.Sub(sendTokens.MulRaw(2)), fooAcc.GetCoins().AmountOf(denom)) - - // test memo - f.TxSend(keyFoo, barAddr, sdk.NewCoin(denom, sendTokens), "--memo='testmemo'", "-y") - tests.WaitForNextNBlocksTM(1, f.Port) - - // Ensure account balances match expected - barAcc = f.QueryAccount(barAddr) - require.Equal(t, sendTokens.MulRaw(3), barAcc.GetCoins().AmountOf(denom)) - fooAcc = f.QueryAccount(fooAddr) - require.Equal(t, startTokens.Sub(sendTokens.MulRaw(3)), fooAcc.GetCoins().AmountOf(denom)) - - f.Cleanup() -} - -func TestGaiaCLIConfirmTx(t *testing.T) { - t.Parallel() - f := InitFixtures(t) - - // start gaiad server - proc := f.GDStart() - defer proc.Stop(false) - - // Save key addresses for later use - fooAddr := f.KeyAddress(keyFoo) - barAddr := f.KeyAddress(keyBar) - - fooAcc := f.QueryAccount(fooAddr) - startTokens := sdk.TokensFromTendermintPower(50) - require.Equal(t, startTokens, fooAcc.GetCoins().AmountOf(denom)) - - // send some tokens from one account to the other - sendTokens := sdk.TokensFromTendermintPower(10) - f.txSendWithConfirm(keyFoo, barAddr, sdk.NewCoin(denom, sendTokens), "Y") - tests.WaitForNextNBlocksTM(1, f.Port) - - // ensure account balances match expected - barAcc := f.QueryAccount(barAddr) - require.Equal(t, sendTokens, barAcc.GetCoins().AmountOf(denom)) - - // send some tokens from one account to the other (cancelling confirmation) - f.txSendWithConfirm(keyFoo, barAddr, sdk.NewCoin(denom, sendTokens), "n") - tests.WaitForNextNBlocksTM(1, f.Port) - - // ensure account balances match expected - barAcc = f.QueryAccount(barAddr) - require.Equal(t, sendTokens, barAcc.GetCoins().AmountOf(denom)) -} - -func TestGaiaCLIGasAuto(t *testing.T) { - t.Parallel() - f := InitFixtures(t) - - // start gaiad server - proc := f.GDStart() - defer proc.Stop(false) - - fooAddr := f.KeyAddress(keyFoo) - barAddr := f.KeyAddress(keyBar) - - fooAcc := f.QueryAccount(fooAddr) - startTokens := sdk.TokensFromTendermintPower(50) - require.Equal(t, startTokens, fooAcc.GetCoins().AmountOf(denom)) - - // Test failure with auto gas disabled and very little gas set by hand - sendTokens := sdk.TokensFromTendermintPower(10) - success, _, _ := f.TxSend(keyFoo, barAddr, sdk.NewCoin(denom, sendTokens), "--gas=10", "-y") - require.False(t, success) - - // Check state didn't change - fooAcc = f.QueryAccount(fooAddr) - require.Equal(t, startTokens, fooAcc.GetCoins().AmountOf(denom)) - - // Test failure with negative gas - success, _, _ = f.TxSend(keyFoo, barAddr, sdk.NewCoin(denom, sendTokens), "--gas=-100", "-y") - require.False(t, success) - - // Check state didn't change - fooAcc = f.QueryAccount(fooAddr) - require.Equal(t, startTokens, fooAcc.GetCoins().AmountOf(denom)) - - // Test failure with 0 gas - success, _, _ = f.TxSend(keyFoo, barAddr, sdk.NewCoin(denom, sendTokens), "--gas=0", "-y") - require.False(t, success) - - // Check state didn't change - fooAcc = f.QueryAccount(fooAddr) - require.Equal(t, startTokens, fooAcc.GetCoins().AmountOf(denom)) - - // Enable auto gas - success, stdout, stderr := f.TxSend(keyFoo, barAddr, sdk.NewCoin(denom, sendTokens), "--gas=auto", "-y") - require.NotEmpty(t, stderr) - require.True(t, success) - cdc := app.MakeCodec() - sendResp := sdk.TxResponse{} - err := cdc.UnmarshalJSON([]byte(stdout), &sendResp) - require.Nil(t, err) - require.True(t, sendResp.GasWanted >= sendResp.GasUsed) - tests.WaitForNextNBlocksTM(1, f.Port) - - // Check state has changed accordingly - fooAcc = f.QueryAccount(fooAddr) - require.Equal(t, startTokens.Sub(sendTokens), fooAcc.GetCoins().AmountOf(denom)) - - f.Cleanup() -} - -func TestGaiaCLICreateValidator(t *testing.T) { - t.Parallel() - f := InitFixtures(t) - - // start gaiad server - proc := f.GDStart() - defer proc.Stop(false) - - barAddr := f.KeyAddress(keyBar) - barVal := sdk.ValAddress(barAddr) - - consPubKey := sdk.MustBech32ifyConsPub(ed25519.GenPrivKey().PubKey()) - - sendTokens := sdk.TokensFromTendermintPower(10) - f.TxSend(keyFoo, barAddr, sdk.NewCoin(denom, sendTokens), "-y") - tests.WaitForNextNBlocksTM(1, f.Port) - - barAcc := f.QueryAccount(barAddr) - require.Equal(t, sendTokens, barAcc.GetCoins().AmountOf(denom)) - - // Generate a create validator transaction and ensure correctness - success, stdout, stderr := f.TxStakingCreateValidator(barAddr.String(), consPubKey, sdk.NewInt64Coin(denom, 2), "--generate-only") - - require.True(f.T, success) - require.Empty(f.T, stderr) - msg := unmarshalStdTx(f.T, stdout) - require.NotZero(t, msg.Fee.Gas) - require.Equal(t, len(msg.Msgs), 1) - require.Equal(t, 0, len(msg.GetSignatures())) - - // Test --dry-run - newValTokens := sdk.TokensFromTendermintPower(2) - success, _, _ = f.TxStakingCreateValidator(keyBar, consPubKey, sdk.NewCoin(denom, newValTokens), "--dry-run") - require.True(t, success) - - // Create the validator - f.TxStakingCreateValidator(keyBar, consPubKey, sdk.NewCoin(denom, newValTokens), "-y") - tests.WaitForNextNBlocksTM(1, f.Port) - - // Ensure funds were deducted properly - barAcc = f.QueryAccount(barAddr) - require.Equal(t, sendTokens.Sub(newValTokens), barAcc.GetCoins().AmountOf(denom)) - - // Ensure that validator state is as expected - validator := f.QueryStakingValidator(barVal) - require.Equal(t, validator.OperatorAddress, barVal) - require.True(sdk.IntEq(t, newValTokens, validator.Tokens)) - - // Query delegations to the validator - validatorDelegations := f.QueryStakingDelegationsTo(barVal) - require.Len(t, validatorDelegations, 1) - require.NotZero(t, validatorDelegations[0].Shares) - - // unbond a single share - unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromTendermintPower(1)) - success = f.TxStakingUnbond(keyBar, unbondAmt.String(), barVal, "-y") - require.True(t, success) - tests.WaitForNextNBlocksTM(1, f.Port) - - // Ensure bonded staking is correct - remainingTokens := newValTokens.Sub(unbondAmt.Amount) - validator = f.QueryStakingValidator(barVal) - require.Equal(t, remainingTokens, validator.Tokens) - - // Get unbonding delegations from the validator - validatorUbds := f.QueryStakingUnbondingDelegationsFrom(barVal) - require.Len(t, validatorUbds, 1) - require.Len(t, validatorUbds[0].Entries, 1) - require.Equal(t, remainingTokens.String(), validatorUbds[0].Entries[0].Balance.String()) - - f.Cleanup() -} - -func TestGaiaCLISubmitProposal(t *testing.T) { - t.Parallel() - f := InitFixtures(t) - - // start gaiad server - proc := f.GDStart() - defer proc.Stop(false) - - f.QueryGovParamDeposit() - f.QueryGovParamVoting() - f.QueryGovParamTallying() - - fooAddr := f.KeyAddress(keyFoo) - - fooAcc := f.QueryAccount(fooAddr) - startTokens := sdk.TokensFromTendermintPower(50) - require.Equal(t, startTokens, fooAcc.GetCoins().AmountOf(sdk.DefaultBondDenom)) - - proposalsQuery := f.QueryGovProposals() - require.Empty(t, proposalsQuery) - - // Test submit generate only for submit proposal - proposalTokens := sdk.TokensFromTendermintPower(5) - success, stdout, stderr := f.TxGovSubmitProposal( - fooAddr.String(), "Text", "Test", "test", sdk.NewCoin(denom, proposalTokens), "--generate-only", "-y") - require.True(t, success) - require.Empty(t, stderr) - msg := unmarshalStdTx(t, stdout) - require.NotZero(t, msg.Fee.Gas) - require.Equal(t, len(msg.Msgs), 1) - require.Equal(t, 0, len(msg.GetSignatures())) - - // Test --dry-run - success, _, _ = f.TxGovSubmitProposal(keyFoo, "Text", "Test", "test", sdk.NewCoin(denom, proposalTokens), "--dry-run") - require.True(t, success) - - // Create the proposal - f.TxGovSubmitProposal(keyFoo, "Text", "Test", "test", sdk.NewCoin(denom, proposalTokens), "-y") - tests.WaitForNextNBlocksTM(1, f.Port) - - // Ensure transaction tags can be queried - txs := f.QueryTxs(1, 50, "action:submit_proposal", fmt.Sprintf("proposer:%s", fooAddr)) - require.Len(t, txs, 1) - - // Ensure deposit was deducted - fooAcc = f.QueryAccount(fooAddr) - require.Equal(t, startTokens.Sub(proposalTokens), fooAcc.GetCoins().AmountOf(denom)) - - // Ensure propsal is directly queryable - proposal1 := f.QueryGovProposal(1) - require.Equal(t, uint64(1), proposal1.ProposalID) - require.Equal(t, gov.StatusDepositPeriod, proposal1.Status) - - // Ensure query proposals returns properly - proposalsQuery = f.QueryGovProposals() - require.Equal(t, uint64(1), proposalsQuery[0].ProposalID) - - // Query the deposits on the proposal - deposit := f.QueryGovDeposit(1, fooAddr) - require.Equal(t, proposalTokens, deposit.Amount.AmountOf(denom)) - - // Test deposit generate only - depositTokens := sdk.TokensFromTendermintPower(10) - success, stdout, stderr = f.TxGovDeposit(1, fooAddr.String(), sdk.NewCoin(denom, depositTokens), "--generate-only") - require.True(t, success) - require.Empty(t, stderr) - msg = unmarshalStdTx(t, stdout) - require.NotZero(t, msg.Fee.Gas) - require.Equal(t, len(msg.Msgs), 1) - require.Equal(t, 0, len(msg.GetSignatures())) - - // Run the deposit transaction - f.TxGovDeposit(1, keyFoo, sdk.NewCoin(denom, depositTokens), "-y") - tests.WaitForNextNBlocksTM(1, f.Port) - - // test query deposit - deposits := f.QueryGovDeposits(1) - require.Len(t, deposits, 1) - require.Equal(t, proposalTokens.Add(depositTokens), deposits[0].Amount.AmountOf(denom)) - - // Ensure querying the deposit returns the proper amount - deposit = f.QueryGovDeposit(1, fooAddr) - require.Equal(t, proposalTokens.Add(depositTokens), deposit.Amount.AmountOf(denom)) - - // Ensure tags are set on the transaction - txs = f.QueryTxs(1, 50, "action:deposit", fmt.Sprintf("depositor:%s", fooAddr)) - require.Len(t, txs, 1) - - // Ensure account has expected amount of funds - fooAcc = f.QueryAccount(fooAddr) - require.Equal(t, startTokens.Sub(proposalTokens.Add(depositTokens)), fooAcc.GetCoins().AmountOf(denom)) - - // Fetch the proposal and ensure it is now in the voting period - proposal1 = f.QueryGovProposal(1) - require.Equal(t, uint64(1), proposal1.ProposalID) - require.Equal(t, gov.StatusVotingPeriod, proposal1.Status) - - // Test vote generate only - success, stdout, stderr = f.TxGovVote(1, gov.OptionYes, fooAddr.String(), "--generate-only") - require.True(t, success) - require.Empty(t, stderr) - msg = unmarshalStdTx(t, stdout) - require.NotZero(t, msg.Fee.Gas) - require.Equal(t, len(msg.Msgs), 1) - require.Equal(t, 0, len(msg.GetSignatures())) - - // Vote on the proposal - f.TxGovVote(1, gov.OptionYes, keyFoo, "-y") - tests.WaitForNextNBlocksTM(1, f.Port) - - // Query the vote - vote := f.QueryGovVote(1, fooAddr) - require.Equal(t, uint64(1), vote.ProposalID) - require.Equal(t, gov.OptionYes, vote.Option) - - // Query the votes - votes := f.QueryGovVotes(1) - require.Len(t, votes, 1) - require.Equal(t, uint64(1), votes[0].ProposalID) - require.Equal(t, gov.OptionYes, votes[0].Option) - - // Ensure tags are applied to voting transaction properly - txs = f.QueryTxs(1, 50, "action:vote", fmt.Sprintf("voter:%s", fooAddr)) - require.Len(t, txs, 1) - - // Ensure no proposals in deposit period - proposalsQuery = f.QueryGovProposals("--status=DepositPeriod") - require.Empty(t, proposalsQuery) - - // Ensure the proposal returns as in the voting period - proposalsQuery = f.QueryGovProposals("--status=VotingPeriod") - require.Equal(t, uint64(1), proposalsQuery[0].ProposalID) - - // submit a second test proposal - f.TxGovSubmitProposal(keyFoo, "Text", "Apples", "test", sdk.NewCoin(denom, proposalTokens), "-y") - tests.WaitForNextNBlocksTM(1, f.Port) - - // Test limit on proposals query - proposalsQuery = f.QueryGovProposals("--limit=1") - require.Equal(t, uint64(2), proposalsQuery[0].ProposalID) - - f.Cleanup() -} - -func TestGaiaCLIQueryTxPagination(t *testing.T) { - t.Parallel() - f := InitFixtures(t) - - // start gaiad server - proc := f.GDStart() - defer proc.Stop(false) - - fooAddr := f.KeyAddress(keyFoo) - barAddr := f.KeyAddress(keyBar) - - accFoo := f.QueryAccount(fooAddr) - seq := accFoo.GetSequence() - - for i := 1; i <= 30; i++ { - success, _, _ := f.TxSend(keyFoo, barAddr, sdk.NewInt64Coin(fooDenom, int64(i)), fmt.Sprintf("--sequence=%d", seq), "-y") - require.True(t, success) - seq++ - } - - // perPage = 15, 2 pages - txsPage1 := f.QueryTxs(1, 15, fmt.Sprintf("sender:%s", fooAddr)) - require.Len(t, txsPage1, 15) - txsPage2 := f.QueryTxs(2, 15, fmt.Sprintf("sender:%s", fooAddr)) - require.Len(t, txsPage2, 15) - require.NotEqual(t, txsPage1, txsPage2) - txsPage3 := f.QueryTxs(3, 15, fmt.Sprintf("sender:%s", fooAddr)) - require.Len(t, txsPage3, 15) - require.Equal(t, txsPage2, txsPage3) - - // perPage = 16, 2 pages - txsPage1 = f.QueryTxs(1, 16, fmt.Sprintf("sender:%s", fooAddr)) - require.Len(t, txsPage1, 16) - txsPage2 = f.QueryTxs(2, 16, fmt.Sprintf("sender:%s", fooAddr)) - require.Len(t, txsPage2, 14) - require.NotEqual(t, txsPage1, txsPage2) - - // perPage = 50 - txsPageFull := f.QueryTxs(1, 50, fmt.Sprintf("sender:%s", fooAddr)) - require.Len(t, txsPageFull, 30) - require.Equal(t, txsPageFull, append(txsPage1, txsPage2...)) - - // perPage = 0 - f.QueryTxsInvalid(errors.New("ERROR: page must greater than 0"), 0, 50, fmt.Sprintf("sender:%s", fooAddr)) - - // limit = 0 - f.QueryTxsInvalid(errors.New("ERROR: limit must greater than 0"), 1, 0, fmt.Sprintf("sender:%s", fooAddr)) -} - -func TestGaiaCLIValidateSignatures(t *testing.T) { - t.Parallel() - f := InitFixtures(t) - - // start gaiad server - proc := f.GDStart() - defer proc.Stop(false) - - fooAddr := f.KeyAddress(keyFoo) - barAddr := f.KeyAddress(keyBar) - - // generate sendTx with default gas - success, stdout, stderr := f.TxSend(fooAddr.String(), barAddr, sdk.NewInt64Coin(denom, 10), "--generate-only") - require.True(t, success) - require.Empty(t, stderr) - - // write unsigned tx to file - unsignedTxFile := WriteToNewTempFile(t, stdout) - defer os.Remove(unsignedTxFile.Name()) - - // validate we can successfully sign - success, stdout, stderr = f.TxSign(keyFoo, unsignedTxFile.Name()) - require.True(t, success) - require.Empty(t, stderr) - stdTx := unmarshalStdTx(t, stdout) - require.Equal(t, len(stdTx.Msgs), 1) - require.Equal(t, 1, len(stdTx.GetSignatures())) - require.Equal(t, fooAddr.String(), stdTx.GetSigners()[0].String()) - - // write signed tx to file - signedTxFile := WriteToNewTempFile(t, stdout) - defer os.Remove(signedTxFile.Name()) - - // validate signatures - success, _, _ = f.TxSign(keyFoo, signedTxFile.Name(), "--validate-signatures") - require.True(t, success) - - // modify the transaction - stdTx.Memo = "MODIFIED-ORIGINAL-TX-BAD" - bz := marshalStdTx(t, stdTx) - modSignedTxFile := WriteToNewTempFile(t, string(bz)) - defer os.Remove(modSignedTxFile.Name()) - - // validate signature validation failure due to different transaction sig bytes - success, _, _ = f.TxSign(keyFoo, modSignedTxFile.Name(), "--validate-signatures") - require.False(t, success) - - f.Cleanup() -} - -func TestGaiaCLISendGenerateSignAndBroadcast(t *testing.T) { - t.Parallel() - f := InitFixtures(t) - - // start gaiad server - proc := f.GDStart() - defer proc.Stop(false) - - fooAddr := f.KeyAddress(keyFoo) - barAddr := f.KeyAddress(keyBar) - - // Test generate sendTx with default gas - sendTokens := sdk.TokensFromTendermintPower(10) - success, stdout, stderr := f.TxSend(fooAddr.String(), barAddr, sdk.NewCoin(denom, sendTokens), "--generate-only") - require.True(t, success) - require.Empty(t, stderr) - msg := unmarshalStdTx(t, stdout) - require.Equal(t, msg.Fee.Gas, uint64(client.DefaultGasLimit)) - require.Equal(t, len(msg.Msgs), 1) - require.Equal(t, 0, len(msg.GetSignatures())) - - // Test generate sendTx with --gas=$amount - success, stdout, stderr = f.TxSend(fooAddr.String(), barAddr, sdk.NewCoin(denom, sendTokens), "--gas=100", "--generate-only") - require.True(t, success) - require.Empty(t, stderr) - msg = unmarshalStdTx(t, stdout) - require.Equal(t, msg.Fee.Gas, uint64(100)) - require.Equal(t, len(msg.Msgs), 1) - require.Equal(t, 0, len(msg.GetSignatures())) - - // Test generate sendTx, estimate gas - success, stdout, stderr = f.TxSend(fooAddr.String(), barAddr, sdk.NewCoin(denom, sendTokens), "--gas=auto", "--generate-only") - require.True(t, success) - require.NotEmpty(t, stderr) - msg = unmarshalStdTx(t, stdout) - require.True(t, msg.Fee.Gas > 0) - require.Equal(t, len(msg.Msgs), 1) - - // Write the output to disk - unsignedTxFile := WriteToNewTempFile(t, stdout) - defer os.Remove(unsignedTxFile.Name()) - - // Test sign --validate-signatures - success, stdout, _ = f.TxSign(keyFoo, unsignedTxFile.Name(), "--validate-signatures") - require.False(t, success) - require.Equal(t, fmt.Sprintf("Signers:\n 0: %v\n\nSignatures:\n\n", fooAddr.String()), stdout) - - // Test sign - success, stdout, _ = f.TxSign(keyFoo, unsignedTxFile.Name()) - require.True(t, success) - msg = unmarshalStdTx(t, stdout) - require.Equal(t, len(msg.Msgs), 1) - require.Equal(t, 1, len(msg.GetSignatures())) - require.Equal(t, fooAddr.String(), msg.GetSigners()[0].String()) - - // Write the output to disk - signedTxFile := WriteToNewTempFile(t, stdout) - defer os.Remove(signedTxFile.Name()) - - // Test sign --validate-signatures - success, stdout, _ = f.TxSign(keyFoo, signedTxFile.Name(), "--validate-signatures") - require.True(t, success) - require.Equal(t, fmt.Sprintf("Signers:\n 0: %v\n\nSignatures:\n 0: %v\t\t\t[OK]\n\n", fooAddr.String(), - fooAddr.String()), stdout) - - // Ensure foo has right amount of funds - fooAcc := f.QueryAccount(fooAddr) - startTokens := sdk.TokensFromTendermintPower(50) - require.Equal(t, startTokens, fooAcc.GetCoins().AmountOf(denom)) - - // Test broadcast - success, stdout, _ = f.TxBroadcast(signedTxFile.Name()) - require.True(t, success) - - var result sdk.TxResponse - - // Unmarshal the response and ensure that gas was properly used - require.Nil(t, app.MakeCodec().UnmarshalJSON([]byte(stdout), &result)) - require.Equal(t, msg.Fee.Gas, uint64(result.GasUsed)) - require.Equal(t, msg.Fee.Gas, uint64(result.GasWanted)) - tests.WaitForNextNBlocksTM(1, f.Port) - - // Ensure account state - barAcc := f.QueryAccount(barAddr) - fooAcc = f.QueryAccount(fooAddr) - require.Equal(t, sendTokens, barAcc.GetCoins().AmountOf(denom)) - require.Equal(t, startTokens.Sub(sendTokens), fooAcc.GetCoins().AmountOf(denom)) - - f.Cleanup() -} - -func TestGaiaCLIMultisignInsufficientCosigners(t *testing.T) { - t.Parallel() - f := InitFixtures(t) - - // start gaiad server with minimum fees - proc := f.GDStart() - defer proc.Stop(false) - - fooBarBazAddr := f.KeyAddress(keyFooBarBaz) - barAddr := f.KeyAddress(keyBar) - - // Send some tokens from one account to the other - success, _, _ := f.TxSend(keyFoo, fooBarBazAddr, sdk.NewInt64Coin(denom, 10), "-y") - require.True(t, success) - tests.WaitForNextNBlocksTM(1, f.Port) - - // Test generate sendTx with multisig - success, stdout, _ := f.TxSend(fooBarBazAddr.String(), barAddr, sdk.NewInt64Coin(denom, 5), "--generate-only") - require.True(t, success) - - // Write the output to disk - unsignedTxFile := WriteToNewTempFile(t, stdout) - defer os.Remove(unsignedTxFile.Name()) - - // Sign with foo's key - success, stdout, _ = f.TxSign(keyFoo, unsignedTxFile.Name(), "--multisig", fooBarBazAddr.String(), "-y") - require.True(t, success) - - // Write the output to disk - fooSignatureFile := WriteToNewTempFile(t, stdout) - defer os.Remove(fooSignatureFile.Name()) - - // Multisign, not enough signatures - success, stdout, _ = f.TxMultisign(unsignedTxFile.Name(), keyFooBarBaz, []string{fooSignatureFile.Name()}) - require.True(t, success) - - // Write the output to disk - signedTxFile := WriteToNewTempFile(t, stdout) - defer os.Remove(signedTxFile.Name()) - - // Validate the multisignature - success, _, _ = f.TxSign(keyFooBarBaz, signedTxFile.Name(), "--validate-signatures") - require.False(t, success) - - // Broadcast the transaction - success, _, _ = f.TxBroadcast(signedTxFile.Name()) - require.False(t, success) -} - -func TestGaiaCLIEncode(t *testing.T) { - t.Parallel() - f := InitFixtures(t) - - // start gaiad server - proc := f.GDStart() - defer proc.Stop(false) - - cdc := app.MakeCodec() - - // Build a testing transaction and write it to disk - barAddr := f.KeyAddress(keyBar) - keyAddr := f.KeyAddress(keyFoo) - - sendTokens := sdk.TokensFromTendermintPower(10) - success, stdout, stderr := f.TxSend(keyAddr.String(), barAddr, sdk.NewCoin(denom, sendTokens), "--generate-only", "--memo", "deadbeef") - require.True(t, success) - require.Empty(t, stderr) - - // Write it to disk - jsonTxFile := WriteToNewTempFile(t, stdout) - defer os.Remove(jsonTxFile.Name()) - - // Run the encode command, and trim the extras from the stdout capture - success, base64Encoded, _ := f.TxEncode(jsonTxFile.Name()) - require.True(t, success) - trimmedBase64 := strings.Trim(base64Encoded, "\"\n") - - // Decode the base64 - decodedBytes, err := base64.StdEncoding.DecodeString(trimmedBase64) - require.Nil(t, err) - - // Check that the transaction decodes as epxceted - var decodedTx auth.StdTx - require.Nil(t, cdc.UnmarshalBinaryLengthPrefixed(decodedBytes, &decodedTx)) - require.Equal(t, "deadbeef", decodedTx.Memo) -} - -func TestGaiaCLIMultisignSortSignatures(t *testing.T) { - t.Parallel() - f := InitFixtures(t) - - // start gaiad server with minimum fees - proc := f.GDStart() - defer proc.Stop(false) - - fooBarBazAddr := f.KeyAddress(keyFooBarBaz) - barAddr := f.KeyAddress(keyBar) - - // Send some tokens from one account to the other - success, _, _ := f.TxSend(keyFoo, fooBarBazAddr, sdk.NewInt64Coin(denom, 10), "-y") - require.True(t, success) - tests.WaitForNextNBlocksTM(1, f.Port) - - // Ensure account balances match expected - fooBarBazAcc := f.QueryAccount(fooBarBazAddr) - require.Equal(t, int64(10), fooBarBazAcc.GetCoins().AmountOf(denom).Int64()) - - // Test generate sendTx with multisig - success, stdout, _ := f.TxSend(fooBarBazAddr.String(), barAddr, sdk.NewInt64Coin(denom, 5), "--generate-only") - require.True(t, success) - - // Write the output to disk - unsignedTxFile := WriteToNewTempFile(t, stdout) - defer os.Remove(unsignedTxFile.Name()) - - // Sign with foo's key - success, stdout, _ = f.TxSign(keyFoo, unsignedTxFile.Name(), "--multisig", fooBarBazAddr.String()) - require.True(t, success) - - // Write the output to disk - fooSignatureFile := WriteToNewTempFile(t, stdout) - defer os.Remove(fooSignatureFile.Name()) - - // Sign with baz's key - success, stdout, _ = f.TxSign(keyBaz, unsignedTxFile.Name(), "--multisig", fooBarBazAddr.String()) - require.True(t, success) - - // Write the output to disk - bazSignatureFile := WriteToNewTempFile(t, stdout) - defer os.Remove(bazSignatureFile.Name()) - - // Multisign, keys in different order - success, stdout, _ = f.TxMultisign(unsignedTxFile.Name(), keyFooBarBaz, []string{ - bazSignatureFile.Name(), fooSignatureFile.Name()}) - require.True(t, success) - - // Write the output to disk - signedTxFile := WriteToNewTempFile(t, stdout) - defer os.Remove(signedTxFile.Name()) - - // Validate the multisignature - success, _, _ = f.TxSign(keyFooBarBaz, signedTxFile.Name(), "--validate-signatures") - require.True(t, success) - - // Broadcast the transaction - success, _, _ = f.TxBroadcast(signedTxFile.Name()) - require.True(t, success) -} - -func TestGaiaCLIMultisign(t *testing.T) { - t.Parallel() - f := InitFixtures(t) - - // start gaiad server with minimum fees - proc := f.GDStart() - defer proc.Stop(false) - - fooBarBazAddr := f.KeyAddress(keyFooBarBaz) - bazAddr := f.KeyAddress(keyBaz) - - // Send some tokens from one account to the other - success, _, _ := f.TxSend(keyFoo, fooBarBazAddr, sdk.NewInt64Coin(denom, 10), "-y") - require.True(t, success) - tests.WaitForNextNBlocksTM(1, f.Port) - - // Ensure account balances match expected - fooBarBazAcc := f.QueryAccount(fooBarBazAddr) - require.Equal(t, int64(10), fooBarBazAcc.GetCoins().AmountOf(denom).Int64()) - - // Test generate sendTx with multisig - success, stdout, stderr := f.TxSend(fooBarBazAddr.String(), bazAddr, sdk.NewInt64Coin(denom, 10), "--generate-only") - require.True(t, success) - require.Empty(t, stderr) - - // Write the output to disk - unsignedTxFile := WriteToNewTempFile(t, stdout) - defer os.Remove(unsignedTxFile.Name()) - - // Sign with foo's key - success, stdout, _ = f.TxSign(keyFoo, unsignedTxFile.Name(), "--multisig", fooBarBazAddr.String(), "-y") - require.True(t, success) - - // Write the output to disk - fooSignatureFile := WriteToNewTempFile(t, stdout) - defer os.Remove(fooSignatureFile.Name()) - - // Sign with bar's key - success, stdout, _ = f.TxSign(keyBar, unsignedTxFile.Name(), "--multisig", fooBarBazAddr.String(), "-y") - require.True(t, success) - - // Write the output to disk - barSignatureFile := WriteToNewTempFile(t, stdout) - defer os.Remove(barSignatureFile.Name()) - - // Multisign - success, stdout, _ = f.TxMultisign(unsignedTxFile.Name(), keyFooBarBaz, []string{ - fooSignatureFile.Name(), barSignatureFile.Name()}) - require.True(t, success) - - // Write the output to disk - signedTxFile := WriteToNewTempFile(t, stdout) - defer os.Remove(signedTxFile.Name()) - - // Validate the multisignature - success, _, _ = f.TxSign(keyFooBarBaz, signedTxFile.Name(), "--validate-signatures", "-y") - require.True(t, success) - - // Broadcast the transaction - success, _, _ = f.TxBroadcast(signedTxFile.Name()) - require.True(t, success) -} - -func TestGaiaCLIConfig(t *testing.T) { - t.Parallel() - f := InitFixtures(t) - node := fmt.Sprintf("%s:%s", f.RPCAddr, f.Port) - - // Set available configuration options - f.CLIConfig("broadcast-mode", "block") - f.CLIConfig("node", node) - f.CLIConfig("output", "text") - f.CLIConfig("trust-node", "true") - f.CLIConfig("chain-id", f.ChainID) - f.CLIConfig("trace", "false") - f.CLIConfig("indent", "true") - - config, err := ioutil.ReadFile(path.Join(f.GCLIHome, "config", "config.toml")) - require.NoError(t, err) - expectedConfig := fmt.Sprintf(`broadcast-mode = "block" -chain-id = "%s" -indent = true -node = "%s" -output = "text" -trace = false -trust-node = true -`, f.ChainID, node) - require.Equal(t, expectedConfig, string(config)) - - f.Cleanup() -} - -func TestGaiadCollectGentxs(t *testing.T) { - t.Parallel() - f := NewFixtures(t) - - // Initialise temporary directories - gentxDir, err := ioutil.TempDir("", "") - gentxDoc := filepath.Join(gentxDir, "gentx.json") - require.NoError(t, err) - - // Reset testing path - f.UnsafeResetAll() - - // Initialize keys - f.KeysAdd(keyFoo) - - // Configure json output - f.CLIConfig("output", "json") - - // Run init - f.GDInit(keyFoo) - - // Add account to genesis.json - f.AddGenesisAccount(f.KeyAddress(keyFoo), startCoins) - - // Write gentx file - f.GenTx(keyFoo, fmt.Sprintf("--output-document=%s", gentxDoc)) - - // Collect gentxs from a custom directory - f.CollectGenTxs(fmt.Sprintf("--gentx-dir=%s", gentxDir)) - - f.Cleanup(gentxDir) -} - -func TestGaiadAddGenesisAccount(t *testing.T) { - t.Parallel() - f := NewFixtures(t) - - // Reset testing path - f.UnsafeResetAll() - - // Initialize keys - f.KeysDelete(keyFoo) - f.KeysDelete(keyBar) - f.KeysDelete(keyBaz) - f.KeysAdd(keyFoo) - f.KeysAdd(keyBar) - f.KeysAdd(keyBaz) - - // Configure json output - f.CLIConfig("output", "json") - - // Run init - f.GDInit(keyFoo) - - // Add account to genesis.json - bazCoins := sdk.Coins{ - sdk.NewInt64Coin("acoin", 1000000), - sdk.NewInt64Coin("bcoin", 1000000), - } - - f.AddGenesisAccount(f.KeyAddress(keyFoo), startCoins) - f.AddGenesisAccount(f.KeyAddress(keyBar), bazCoins) - genesisState := f.GenesisState() - require.Equal(t, genesisState.Accounts[0].Address, f.KeyAddress(keyFoo)) - require.Equal(t, genesisState.Accounts[1].Address, f.KeyAddress(keyBar)) - require.True(t, genesisState.Accounts[0].Coins.IsEqual(startCoins)) - require.True(t, genesisState.Accounts[1].Coins.IsEqual(bazCoins)) -} - -func TestSlashingGetParams(t *testing.T) { - t.Parallel() - f := InitFixtures(t) - - // start gaiad server - proc := f.GDStart() - defer proc.Stop(false) - - params := f.QuerySlashingParams() - require.Equal(t, time.Duration(120000000000), params.MaxEvidenceAge) - require.Equal(t, int64(100), params.SignedBlocksWindow) - require.Equal(t, sdk.NewDecWithPrec(5, 1), params.MinSignedPerWindow) - - sinfo := f.QuerySigningInfo(f.GDTendermint("show-validator")) - require.Equal(t, int64(0), sinfo.StartHeight) - require.False(t, sinfo.Tombstoned) -} - -func TestValidateGenesis(t *testing.T) { - t.Parallel() - f := InitFixtures(t) - - // start gaiad server - proc := f.GDStart() - defer proc.Stop(false) - - f.ValidateGenesis() -} diff --git a/gaia/cli_test/doc.go b/gaia/cli_test/doc.go deleted file mode 100644 index bcf9c5e4..00000000 --- a/gaia/cli_test/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -package clitest - -// package clitest runs integration tests which make use of CLI commands. diff --git a/gaia/cli_test/test_helpers.go b/gaia/cli_test/test_helpers.go deleted file mode 100644 index a05e967e..00000000 --- a/gaia/cli_test/test_helpers.go +++ /dev/null @@ -1,685 +0,0 @@ -package clitest - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "os" - "path/filepath" - "strings" - "testing" - "time" - - "github.com/stretchr/testify/require" - - cmn "github.com/tendermint/tendermint/libs/common" - - clientkeys "github.com/cosmos/cosmos-sdk/client/keys" - "github.com/cosmos/cosmos-sdk/cmd/gaia/app" - appInit "github.com/cosmos/cosmos-sdk/cmd/gaia/init" - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/crypto/keys" - "github.com/cosmos/cosmos-sdk/server" - "github.com/cosmos/cosmos-sdk/tests" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/cosmos/cosmos-sdk/x/gov" - "github.com/cosmos/cosmos-sdk/x/slashing" - "github.com/cosmos/cosmos-sdk/x/staking" -) - -const ( - denom = "stake" - keyFoo = "foo" - keyBar = "bar" - fooDenom = "footoken" - feeDenom = "feetoken" - fee2Denom = "fee2token" - keyBaz = "baz" - keyVesting = "vesting" - keyFooBarBaz = "foobarbaz" -) - -var ( - startCoins = sdk.Coins{ - sdk.NewCoin(feeDenom, sdk.TokensFromTendermintPower(1000000)), - sdk.NewCoin(fee2Denom, sdk.TokensFromTendermintPower(1000000)), - sdk.NewCoin(fooDenom, sdk.TokensFromTendermintPower(1000)), - sdk.NewCoin(denom, sdk.TokensFromTendermintPower(150)), - } - - vestingCoins = sdk.Coins{ - sdk.NewCoin(feeDenom, sdk.TokensFromTendermintPower(500000)), - } -) - -//___________________________________________________________________________________ -// Fixtures - -// Fixtures is used to setup the testing environment -type Fixtures struct { - ChainID string - RPCAddr string - Port string - GDHome string - GCLIHome string - P2PAddr string - T *testing.T -} - -// NewFixtures creates a new instance of Fixtures with many vars set -func NewFixtures(t *testing.T) *Fixtures { - tmpDir, err := ioutil.TempDir("", "gaia_integration_"+t.Name()+"_") - require.NoError(t, err) - - servAddr, port, err := server.FreeTCPAddr() - require.NoError(t, err) - - p2pAddr, _, err := server.FreeTCPAddr() - require.NoError(t, err) - - return &Fixtures{ - T: t, - GDHome: filepath.Join(tmpDir, ".gaiad"), - GCLIHome: filepath.Join(tmpDir, ".gaiacli"), - RPCAddr: servAddr, - P2PAddr: p2pAddr, - Port: port, - } -} - -// GenesisFile returns the path of the genesis file -func (f Fixtures) GenesisFile() string { - return filepath.Join(f.GDHome, "config", "genesis.json") -} - -// GenesisFile returns the application's genesis state -func (f Fixtures) GenesisState() app.GenesisState { - cdc := codec.New() - genDoc, err := appInit.LoadGenesisDoc(cdc, f.GenesisFile()) - require.NoError(f.T, err) - - var appState app.GenesisState - require.NoError(f.T, cdc.UnmarshalJSON(genDoc.AppState, &appState)) - return appState -} - -// InitFixtures is called at the beginning of a test and initializes a chain -// with 1 validator. -func InitFixtures(t *testing.T) (f *Fixtures) { - f = NewFixtures(t) - - // reset test state - f.UnsafeResetAll() - - // ensure keystore has foo and bar keys - f.KeysDelete(keyFoo) - f.KeysDelete(keyBar) - f.KeysDelete(keyBar) - f.KeysDelete(keyFooBarBaz) - f.KeysAdd(keyFoo) - f.KeysAdd(keyBar) - f.KeysAdd(keyBaz) - f.KeysAdd(keyVesting) - f.KeysAdd(keyFooBarBaz, "--multisig-threshold=2", fmt.Sprintf( - "--multisig=%s,%s,%s", keyFoo, keyBar, keyBaz)) - - // ensure that CLI output is in JSON format - f.CLIConfig("output", "json") - - // NOTE: GDInit sets the ChainID - f.GDInit(keyFoo) - - f.CLIConfig("chain-id", f.ChainID) - f.CLIConfig("broadcast-mode", "block") - - // start an account with tokens - f.AddGenesisAccount(f.KeyAddress(keyFoo), startCoins) - f.AddGenesisAccount( - f.KeyAddress(keyVesting), startCoins, - fmt.Sprintf("--vesting-amount=%s", vestingCoins), - fmt.Sprintf("--vesting-start-time=%d", time.Now().UTC().UnixNano()), - fmt.Sprintf("--vesting-end-time=%d", time.Now().Add(60*time.Second).UTC().UnixNano()), - ) - - f.GenTx(keyFoo) - f.CollectGenTxs() - - return -} - -// Cleanup is meant to be run at the end of a test to clean up an remaining test state -func (f *Fixtures) Cleanup(dirs ...string) { - clean := append(dirs, f.GDHome, f.GCLIHome) - for _, d := range clean { - err := os.RemoveAll(d) - require.NoError(f.T, err) - } -} - -// Flags returns the flags necessary for making most CLI calls -func (f *Fixtures) Flags() string { - return fmt.Sprintf("--home=%s --node=%s", f.GCLIHome, f.RPCAddr) -} - -//___________________________________________________________________________________ -// gaiad - -// UnsafeResetAll is gaiad unsafe-reset-all -func (f *Fixtures) UnsafeResetAll(flags ...string) { - cmd := fmt.Sprintf("../../../build/gaiad --home=%s unsafe-reset-all", f.GDHome) - executeWrite(f.T, addFlags(cmd, flags)) - err := os.RemoveAll(filepath.Join(f.GDHome, "config", "gentx")) - require.NoError(f.T, err) -} - -// GDInit is gaiad init -// NOTE: GDInit sets the ChainID for the Fixtures instance -func (f *Fixtures) GDInit(moniker string, flags ...string) { - cmd := fmt.Sprintf("../../../build/gaiad init -o --home=%s %s", f.GDHome, moniker) - _, stderr := tests.ExecuteT(f.T, addFlags(cmd, flags), app.DefaultKeyPass) - - var chainID string - var initRes map[string]json.RawMessage - - err := json.Unmarshal([]byte(stderr), &initRes) - require.NoError(f.T, err) - - err = json.Unmarshal(initRes["chain_id"], &chainID) - require.NoError(f.T, err) - - f.ChainID = chainID -} - -// AddGenesisAccount is gaiad add-genesis-account -func (f *Fixtures) AddGenesisAccount(address sdk.AccAddress, coins sdk.Coins, flags ...string) { - cmd := fmt.Sprintf("../../../build/gaiad add-genesis-account %s %s --home=%s", address, coins, f.GDHome) - executeWriteCheckErr(f.T, addFlags(cmd, flags)) -} - -// GenTx is gaiad gentx -func (f *Fixtures) GenTx(name string, flags ...string) { - cmd := fmt.Sprintf("../../../build/gaiad gentx --name=%s --home=%s --home-client=%s", name, f.GDHome, f.GCLIHome) - executeWriteCheckErr(f.T, addFlags(cmd, flags), app.DefaultKeyPass) -} - -// CollectGenTxs is gaiad collect-gentxs -func (f *Fixtures) CollectGenTxs(flags ...string) { - cmd := fmt.Sprintf("../../../build/gaiad collect-gentxs --home=%s", f.GDHome) - executeWriteCheckErr(f.T, addFlags(cmd, flags), app.DefaultKeyPass) -} - -// GDStart runs gaiad start with the appropriate flags and returns a process -func (f *Fixtures) GDStart(flags ...string) *tests.Process { - cmd := fmt.Sprintf("../../../build/gaiad start --home=%s --rpc.laddr=%v --p2p.laddr=%v", f.GDHome, f.RPCAddr, f.P2PAddr) - proc := tests.GoExecuteTWithStdout(f.T, addFlags(cmd, flags)) - tests.WaitForTMStart(f.Port) - tests.WaitForNextNBlocksTM(1, f.Port) - return proc -} - -// GDTendermint returns the results of gaiad tendermint [query] -func (f *Fixtures) GDTendermint(query string) string { - cmd := fmt.Sprintf("../../../build/gaiad tendermint %s --home=%s", query, f.GDHome) - success, stdout, stderr := executeWriteRetStdStreams(f.T, cmd) - require.Empty(f.T, stderr) - require.True(f.T, success) - return strings.TrimSpace(stdout) -} - -// ValidateGenesis runs gaiad validate-genesis -func (f *Fixtures) ValidateGenesis() { - cmd := fmt.Sprintf("../../../build/gaiad validate-genesis --home=%s", f.GDHome) - executeWriteCheckErr(f.T, cmd) -} - -//___________________________________________________________________________________ -// gaiacli keys - -// KeysDelete is gaiacli keys delete -func (f *Fixtures) KeysDelete(name string, flags ...string) { - cmd := fmt.Sprintf("../../../build/gaiacli keys delete --home=%s %s", f.GCLIHome, name) - executeWrite(f.T, addFlags(cmd, append(append(flags, "-y"), "-f"))) -} - -// KeysAdd is gaiacli keys add -func (f *Fixtures) KeysAdd(name string, flags ...string) { - cmd := fmt.Sprintf("../../../build/gaiacli keys add --home=%s %s", f.GCLIHome, name) - executeWriteCheckErr(f.T, addFlags(cmd, flags), app.DefaultKeyPass) -} - -// KeysAddRecover prepares gaiacli keys add --recover -func (f *Fixtures) KeysAddRecover(name, mnemonic string, flags ...string) (exitSuccess bool, stdout, stderr string) { - cmd := fmt.Sprintf("../../../build/gaiacli keys add --home=%s --recover %s", f.GCLIHome, name) - return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), app.DefaultKeyPass, mnemonic) -} - -// KeysAddRecoverHDPath prepares gaiacli keys add --recover --account --index -func (f *Fixtures) KeysAddRecoverHDPath(name, mnemonic string, account uint32, index uint32, flags ...string) { - cmd := fmt.Sprintf("../../../build/gaiacli keys add --home=%s --recover %s --account %d --index %d", f.GCLIHome, name, account, index) - executeWriteCheckErr(f.T, addFlags(cmd, flags), app.DefaultKeyPass, mnemonic) -} - -// KeysShow is gaiacli keys show -func (f *Fixtures) KeysShow(name string, flags ...string) keys.KeyOutput { - cmd := fmt.Sprintf("../../../build/gaiacli keys show --home=%s %s", f.GCLIHome, name) - out, _ := tests.ExecuteT(f.T, addFlags(cmd, flags), "") - var ko keys.KeyOutput - err := clientkeys.UnmarshalJSON([]byte(out), &ko) - require.NoError(f.T, err) - return ko -} - -// KeyAddress returns the SDK account address from the key -func (f *Fixtures) KeyAddress(name string) sdk.AccAddress { - ko := f.KeysShow(name) - accAddr, err := sdk.AccAddressFromBech32(ko.Address) - require.NoError(f.T, err) - return accAddr -} - -//___________________________________________________________________________________ -// gaiacli config - -// CLIConfig is gaiacli config -func (f *Fixtures) CLIConfig(key, value string, flags ...string) { - cmd := fmt.Sprintf("../../../build/gaiacli config --home=%s %s %s", f.GCLIHome, key, value) - executeWriteCheckErr(f.T, addFlags(cmd, flags)) -} - -//___________________________________________________________________________________ -// gaiacli tx send/sign/broadcast - -// TxSend is gaiacli tx send -func (f *Fixtures) TxSend(from string, to sdk.AccAddress, amount sdk.Coin, flags ...string) (bool, string, string) { - cmd := fmt.Sprintf("../../../build/gaiacli tx send %s %s %v --from=%s", to, amount, f.Flags(), from) - return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), app.DefaultKeyPass) -} - -func (f *Fixtures) txSendWithConfirm( - from string, to sdk.AccAddress, amount sdk.Coin, confirm string, flags ...string, -) (bool, string, string) { - - cmd := fmt.Sprintf("../../../build/gaiacli tx send %s %s %v --from=%s", to, amount, f.Flags(), from) - return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), confirm, app.DefaultKeyPass) -} - -// TxSign is gaiacli tx sign -func (f *Fixtures) TxSign(signer, fileName string, flags ...string) (bool, string, string) { - cmd := fmt.Sprintf("../../../build/gaiacli tx sign %v --from=%s %v", f.Flags(), signer, fileName) - return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), app.DefaultKeyPass) -} - -// TxBroadcast is gaiacli tx broadcast -func (f *Fixtures) TxBroadcast(fileName string, flags ...string) (bool, string, string) { - cmd := fmt.Sprintf("../../../build/gaiacli tx broadcast %v %v", f.Flags(), fileName) - return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), app.DefaultKeyPass) -} - -// TxEncode is gaiacli tx encode -func (f *Fixtures) TxEncode(fileName string, flags ...string) (bool, string, string) { - cmd := fmt.Sprintf("../../../build/gaiacli tx encode %v %v", f.Flags(), fileName) - return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), app.DefaultKeyPass) -} - -// TxMultisign is gaiacli tx multisign -func (f *Fixtures) TxMultisign(fileName, name string, signaturesFiles []string, - flags ...string) (bool, string, string) { - - cmd := fmt.Sprintf("../../../build/gaiacli tx multisign %v %s %s %s", f.Flags(), - fileName, name, strings.Join(signaturesFiles, " "), - ) - return executeWriteRetStdStreams(f.T, cmd) -} - -//___________________________________________________________________________________ -// gaiacli tx staking - -// TxStakingCreateValidator is gaiacli tx staking create-validator -func (f *Fixtures) TxStakingCreateValidator(from, consPubKey string, amount sdk.Coin, flags ...string) (bool, string, string) { - cmd := fmt.Sprintf("../../../build/gaiacli tx staking create-validator %v --from=%s --pubkey=%s", f.Flags(), from, consPubKey) - cmd += fmt.Sprintf(" --amount=%v --moniker=%v --commission-rate=%v", amount, from, "0.05") - cmd += fmt.Sprintf(" --commission-max-rate=%v --commission-max-change-rate=%v", "0.20", "0.10") - cmd += fmt.Sprintf(" --min-self-delegation=%v", "1") - return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), app.DefaultKeyPass) -} - -// TxStakingUnbond is gaiacli tx staking unbond -func (f *Fixtures) TxStakingUnbond(from, shares string, validator sdk.ValAddress, flags ...string) bool { - cmd := fmt.Sprintf("../../../build/gaiacli tx staking unbond %s %v --from=%s %v", validator, shares, from, f.Flags()) - return executeWrite(f.T, addFlags(cmd, flags), app.DefaultKeyPass) -} - -//___________________________________________________________________________________ -// gaiacli tx gov - -// TxGovSubmitProposal is gaiacli tx gov submit-proposal -func (f *Fixtures) TxGovSubmitProposal(from, typ, title, description string, deposit sdk.Coin, flags ...string) (bool, string, string) { - cmd := fmt.Sprintf("../../../build/gaiacli tx gov submit-proposal %v --from=%s --type=%s", f.Flags(), from, typ) - cmd += fmt.Sprintf(" --title=%s --description=%s --deposit=%s", title, description, deposit) - return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), app.DefaultKeyPass) -} - -// TxGovDeposit is gaiacli tx gov deposit -func (f *Fixtures) TxGovDeposit(proposalID int, from string, amount sdk.Coin, flags ...string) (bool, string, string) { - cmd := fmt.Sprintf("../../../build/gaiacli tx gov deposit %d %s --from=%s %v", proposalID, amount, from, f.Flags()) - return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), app.DefaultKeyPass) -} - -// TxGovVote is gaiacli tx gov vote -func (f *Fixtures) TxGovVote(proposalID int, option gov.VoteOption, from string, flags ...string) (bool, string, string) { - cmd := fmt.Sprintf("../../../build/gaiacli tx gov vote %d %s --from=%s %v", proposalID, option, from, f.Flags()) - return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), app.DefaultKeyPass) -} - -//___________________________________________________________________________________ -// gaiacli query account - -// QueryAccount is gaiacli query account -func (f *Fixtures) QueryAccount(address sdk.AccAddress, flags ...string) auth.BaseAccount { - cmd := fmt.Sprintf("../../../build/gaiacli query account %s %v", address, f.Flags()) - out, _ := tests.ExecuteT(f.T, addFlags(cmd, flags), "") - var initRes map[string]json.RawMessage - err := json.Unmarshal([]byte(out), &initRes) - require.NoError(f.T, err, "out %v, err %v", out, err) - value := initRes["value"] - var acc auth.BaseAccount - cdc := codec.New() - codec.RegisterCrypto(cdc) - err = cdc.UnmarshalJSON(value, &acc) - require.NoError(f.T, err, "value %v, err %v", string(value), err) - return acc -} - -//___________________________________________________________________________________ -// gaiacli query txs - -// QueryTxs is gaiacli query txs -func (f *Fixtures) QueryTxs(page, limit int, tags ...string) []sdk.TxResponse { - cmd := fmt.Sprintf("../../../build/gaiacli query txs --page=%d --limit=%d --tags='%s' %v", page, limit, queryTags(tags), f.Flags()) - out, _ := tests.ExecuteT(f.T, cmd, "") - var txs []sdk.TxResponse - cdc := app.MakeCodec() - err := cdc.UnmarshalJSON([]byte(out), &txs) - require.NoError(f.T, err, "out %v\n, err %v", out, err) - return txs -} - -// QueryTxsInvalid query txs with wrong parameters and compare expected error -func (f *Fixtures) QueryTxsInvalid(expectedErr error, page, limit int, tags ...string) { - cmd := fmt.Sprintf("../../../build/gaiacli query txs --page=%d --limit=%d --tags='%s' %v", page, limit, queryTags(tags), f.Flags()) - _, err := tests.ExecuteT(f.T, cmd, "") - require.EqualError(f.T, expectedErr, err) -} - -//___________________________________________________________________________________ -// gaiacli query staking - -// QueryStakingValidator is gaiacli query staking validator -func (f *Fixtures) QueryStakingValidator(valAddr sdk.ValAddress, flags ...string) staking.Validator { - cmd := fmt.Sprintf("../../../build/gaiacli query staking validator %s %v", valAddr, f.Flags()) - out, _ := tests.ExecuteT(f.T, addFlags(cmd, flags), "") - var validator staking.Validator - cdc := app.MakeCodec() - err := cdc.UnmarshalJSON([]byte(out), &validator) - require.NoError(f.T, err, "out %v\n, err %v", out, err) - return validator -} - -// QueryStakingUnbondingDelegationsFrom is gaiacli query staking unbonding-delegations-from -func (f *Fixtures) QueryStakingUnbondingDelegationsFrom(valAddr sdk.ValAddress, flags ...string) []staking.UnbondingDelegation { - cmd := fmt.Sprintf("../../../build/gaiacli query staking unbonding-delegations-from %s %v", valAddr, f.Flags()) - out, _ := tests.ExecuteT(f.T, addFlags(cmd, flags), "") - var ubds []staking.UnbondingDelegation - cdc := app.MakeCodec() - err := cdc.UnmarshalJSON([]byte(out), &ubds) - require.NoError(f.T, err, "out %v\n, err %v", out, err) - return ubds -} - -// QueryStakingDelegationsTo is gaiacli query staking delegations-to -func (f *Fixtures) QueryStakingDelegationsTo(valAddr sdk.ValAddress, flags ...string) []staking.Delegation { - cmd := fmt.Sprintf("../../../build/gaiacli query staking delegations-to %s %v", valAddr, f.Flags()) - out, _ := tests.ExecuteT(f.T, addFlags(cmd, flags), "") - var delegations []staking.Delegation - cdc := app.MakeCodec() - err := cdc.UnmarshalJSON([]byte(out), &delegations) - require.NoError(f.T, err, "out %v\n, err %v", out, err) - return delegations -} - -// QueryStakingPool is gaiacli query staking pool -func (f *Fixtures) QueryStakingPool(flags ...string) staking.Pool { - cmd := fmt.Sprintf("../../../build/gaiacli query staking pool %v", f.Flags()) - out, _ := tests.ExecuteT(f.T, addFlags(cmd, flags), "") - var pool staking.Pool - cdc := app.MakeCodec() - err := cdc.UnmarshalJSON([]byte(out), &pool) - require.NoError(f.T, err, "out %v\n, err %v", out, err) - return pool -} - -// QueryStakingParameters is gaiacli query staking parameters -func (f *Fixtures) QueryStakingParameters(flags ...string) staking.Params { - cmd := fmt.Sprintf("../../../build/gaiacli query staking params %v", f.Flags()) - out, _ := tests.ExecuteT(f.T, addFlags(cmd, flags), "") - var params staking.Params - cdc := app.MakeCodec() - err := cdc.UnmarshalJSON([]byte(out), ¶ms) - require.NoError(f.T, err, "out %v\n, err %v", out, err) - return params -} - -//___________________________________________________________________________________ -// gaiacli query gov - -// QueryGovParamDeposit is gaiacli query gov param deposit -func (f *Fixtures) QueryGovParamDeposit() gov.DepositParams { - cmd := fmt.Sprintf("../../../build/gaiacli query gov param deposit %s", f.Flags()) - out, _ := tests.ExecuteT(f.T, cmd, "") - var depositParam gov.DepositParams - cdc := app.MakeCodec() - err := cdc.UnmarshalJSON([]byte(out), &depositParam) - require.NoError(f.T, err, "out %v\n, err %v", out, err) - return depositParam -} - -// QueryGovParamVoting is gaiacli query gov param voting -func (f *Fixtures) QueryGovParamVoting() gov.VotingParams { - cmd := fmt.Sprintf("../../../build/gaiacli query gov param voting %s", f.Flags()) - out, _ := tests.ExecuteT(f.T, cmd, "") - var votingParam gov.VotingParams - cdc := app.MakeCodec() - err := cdc.UnmarshalJSON([]byte(out), &votingParam) - require.NoError(f.T, err, "out %v\n, err %v", out, err) - return votingParam -} - -// QueryGovParamTallying is gaiacli query gov param tallying -func (f *Fixtures) QueryGovParamTallying() gov.TallyParams { - cmd := fmt.Sprintf("../../../build/gaiacli query gov param tallying %s", f.Flags()) - out, _ := tests.ExecuteT(f.T, cmd, "") - var tallyingParam gov.TallyParams - cdc := app.MakeCodec() - err := cdc.UnmarshalJSON([]byte(out), &tallyingParam) - require.NoError(f.T, err, "out %v\n, err %v", out, err) - return tallyingParam -} - -// QueryGovProposals is gaiacli query gov proposals -func (f *Fixtures) QueryGovProposals(flags ...string) gov.Proposals { - cmd := fmt.Sprintf("../../../build/gaiacli query gov proposals %v", f.Flags()) - stdout, stderr := tests.ExecuteT(f.T, addFlags(cmd, flags), "") - if strings.Contains(stderr, "No matching proposals found") { - return gov.Proposals{} - } - require.Empty(f.T, stderr) - var out gov.Proposals - cdc := app.MakeCodec() - err := cdc.UnmarshalJSON([]byte(stdout), &out) - require.NoError(f.T, err) - return out -} - -// QueryGovProposal is gaiacli query gov proposal -func (f *Fixtures) QueryGovProposal(proposalID int, flags ...string) gov.Proposal { - cmd := fmt.Sprintf("../../../build/gaiacli query gov proposal %d %v", proposalID, f.Flags()) - out, _ := tests.ExecuteT(f.T, addFlags(cmd, flags), "") - var proposal gov.Proposal - cdc := app.MakeCodec() - err := cdc.UnmarshalJSON([]byte(out), &proposal) - require.NoError(f.T, err, "out %v\n, err %v", out, err) - return proposal -} - -// QueryGovVote is gaiacli query gov vote -func (f *Fixtures) QueryGovVote(proposalID int, voter sdk.AccAddress, flags ...string) gov.Vote { - cmd := fmt.Sprintf("../../../build/gaiacli query gov vote %d %s %v", proposalID, voter, f.Flags()) - out, _ := tests.ExecuteT(f.T, addFlags(cmd, flags), "") - var vote gov.Vote - cdc := app.MakeCodec() - err := cdc.UnmarshalJSON([]byte(out), &vote) - require.NoError(f.T, err, "out %v\n, err %v", out, err) - return vote -} - -// QueryGovVotes is gaiacli query gov votes -func (f *Fixtures) QueryGovVotes(proposalID int, flags ...string) []gov.Vote { - cmd := fmt.Sprintf("../../../build/gaiacli query gov votes %d %v", proposalID, f.Flags()) - out, _ := tests.ExecuteT(f.T, addFlags(cmd, flags), "") - var votes []gov.Vote - cdc := app.MakeCodec() - err := cdc.UnmarshalJSON([]byte(out), &votes) - require.NoError(f.T, err, "out %v\n, err %v", out, err) - return votes -} - -// QueryGovDeposit is gaiacli query gov deposit -func (f *Fixtures) QueryGovDeposit(proposalID int, depositor sdk.AccAddress, flags ...string) gov.Deposit { - cmd := fmt.Sprintf("../../../build/gaiacli query gov deposit %d %s %v", proposalID, depositor, f.Flags()) - out, _ := tests.ExecuteT(f.T, addFlags(cmd, flags), "") - var deposit gov.Deposit - cdc := app.MakeCodec() - err := cdc.UnmarshalJSON([]byte(out), &deposit) - require.NoError(f.T, err, "out %v\n, err %v", out, err) - return deposit -} - -// QueryGovDeposits is gaiacli query gov deposits -func (f *Fixtures) QueryGovDeposits(propsalID int, flags ...string) []gov.Deposit { - cmd := fmt.Sprintf("../../../build/gaiacli query gov deposits %d %v", propsalID, f.Flags()) - out, _ := tests.ExecuteT(f.T, addFlags(cmd, flags), "") - var deposits []gov.Deposit - cdc := app.MakeCodec() - err := cdc.UnmarshalJSON([]byte(out), &deposits) - require.NoError(f.T, err, "out %v\n, err %v", out, err) - return deposits -} - -//___________________________________________________________________________________ -// query slashing - -// QuerySigningInfo returns the signing info for a validator -func (f *Fixtures) QuerySigningInfo(val string) slashing.ValidatorSigningInfo { - cmd := fmt.Sprintf("../../../build/gaiacli query slashing signing-info %s %s", val, f.Flags()) - res, errStr := tests.ExecuteT(f.T, cmd, "") - require.Empty(f.T, errStr) - cdc := app.MakeCodec() - var sinfo slashing.ValidatorSigningInfo - err := cdc.UnmarshalJSON([]byte(res), &sinfo) - require.NoError(f.T, err) - return sinfo -} - -// QuerySlashingParams is gaiacli query slashing params -func (f *Fixtures) QuerySlashingParams() slashing.Params { - cmd := fmt.Sprintf("../../../build/gaiacli query slashing params %s", f.Flags()) - res, errStr := tests.ExecuteT(f.T, cmd, "") - require.Empty(f.T, errStr) - cdc := app.MakeCodec() - var params slashing.Params - err := cdc.UnmarshalJSON([]byte(res), ¶ms) - require.NoError(f.T, err) - return params -} - -//___________________________________________________________________________________ -// executors - -func executeWriteCheckErr(t *testing.T, cmdStr string, writes ...string) { - require.True(t, executeWrite(t, cmdStr, writes...)) -} - -func executeWrite(t *testing.T, cmdStr string, writes ...string) (exitSuccess bool) { - exitSuccess, _, _ = executeWriteRetStdStreams(t, cmdStr, writes...) - return -} - -func executeWriteRetStdStreams(t *testing.T, cmdStr string, writes ...string) (bool, string, string) { - proc := tests.GoExecuteT(t, cmdStr) - - // Enables use of interactive commands - for _, write := range writes { - _, err := proc.StdinPipe.Write([]byte(write + "\n")) - require.NoError(t, err) - } - - // Read both stdout and stderr from the process - stdout, stderr, err := proc.ReadAll() - if err != nil { - fmt.Println("Err on proc.ReadAll()", err, cmdStr) - } - - // Log output. - if len(stdout) > 0 { - t.Log("Stdout:", cmn.Green(string(stdout))) - } - if len(stderr) > 0 { - t.Log("Stderr:", cmn.Red(string(stderr))) - } - - // Wait for process to exit - proc.Wait() - - // Return succes, stdout, stderr - return proc.ExitState.Success(), string(stdout), string(stderr) -} - -//___________________________________________________________________________________ -// utils - -func addFlags(cmd string, flags []string) string { - for _, f := range flags { - cmd += " " + f - } - return strings.TrimSpace(cmd) -} - -func queryTags(tags []string) (out string) { - for _, tag := range tags { - out += tag + "&" - } - return strings.TrimSuffix(out, "&") -} - -// Write the given string to a new temporary file -func WriteToNewTempFile(t *testing.T, s string) *os.File { - fp, err := ioutil.TempFile(os.TempDir(), "cosmos_cli_test_") - require.Nil(t, err) - _, err = fp.WriteString(s) - require.Nil(t, err) - return fp -} - -func marshalStdTx(t *testing.T, stdTx auth.StdTx) []byte { - cdc := app.MakeCodec() - bz, err := cdc.MarshalBinaryBare(stdTx) - require.NoError(t, err) - return bz -} - -func unmarshalStdTx(t *testing.T, s string) (stdTx auth.StdTx) { - cdc := app.MakeCodec() - require.Nil(t, cdc.UnmarshalJSON([]byte(s), &stdTx)) - return -} diff --git a/gaia/cmd/gaiadebug/README.md b/gaia/cmd/gaiadebug/README.md deleted file mode 100644 index c2f0b8bc..00000000 --- a/gaia/cmd/gaiadebug/README.md +++ /dev/null @@ -1,35 +0,0 @@ -# Gaiadebug - -Simple tool for simple debugging. - -We try to accept both hex and base64 formats and provide a useful response. - -Note we often encode bytes as hex in the logs, but as base64 in the JSON. - -## Pubkeys - -The following give the same result: - -``` -gaiadebug pubkey TZTQnfqOsi89SeoXVnIw+tnFJnr4X8qVC0U8AsEmFk4= -gaiadebug pubkey 4D94D09DFA8EB22F3D49EA17567230FAD9C5267AF85FCA950B453C02C126164E -``` - -## Txs - -Pass in a hex/base64 tx and get back the full JSON - -``` -gaiadebug tx -``` - -## Hack - -This is a command with boilerplate for using Go as a scripting language to hack -on an existing Gaia state. - -Currently we have an example for the state of gaia-6001 after it -[crashed](https://github.com/cosmos/cosmos-sdk/blob/master/cmd/gaia/testnets/STATUS.md#june-13-2018-230-est---published-postmortem-of-gaia-6001-failure). -If you run `gaiadebug hack $HOME/.gaiad` on that -state, it will do a binary search on the state history to find when the state -invariant was violated. diff --git a/gaia/cmd/gaiadebug/hack.go b/gaia/cmd/gaiadebug/hack.go deleted file mode 100644 index 51927592..00000000 --- a/gaia/cmd/gaiadebug/hack.go +++ /dev/null @@ -1,268 +0,0 @@ -package main - -import ( - "encoding/base64" - "encoding/hex" - "fmt" - "os" - "path" - - "github.com/cosmos/cosmos-sdk/store" - - "github.com/cosmos/cosmos-sdk/baseapp" - - "github.com/spf13/cobra" - "github.com/spf13/viper" - abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/crypto/ed25519" - - cmn "github.com/tendermint/tendermint/libs/common" - dbm "github.com/tendermint/tendermint/libs/db" - "github.com/tendermint/tendermint/libs/log" - - bam "github.com/cosmos/cosmos-sdk/baseapp" - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/cosmos/cosmos-sdk/x/bank" - "github.com/cosmos/cosmos-sdk/x/params" - "github.com/cosmos/cosmos-sdk/x/slashing" - "github.com/cosmos/cosmos-sdk/x/staking" - - gaia "github.com/cosmos/cosmos-sdk/cmd/gaia/app" -) - -func runHackCmd(cmd *cobra.Command, args []string) error { - - if len(args) != 1 { - return fmt.Errorf("Expected 1 arg") - } - - // ".gaiad" - dataDir := args[0] - dataDir = path.Join(dataDir, "data") - - // load the app - logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)) - db, err := sdk.NewLevelDB("gaia", dataDir) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - app := NewGaiaApp(logger, db, baseapp.SetPruning(store.NewPruningOptionsFromString(viper.GetString("pruning")))) - - // print some info - id := app.LastCommitID() - lastBlockHeight := app.LastBlockHeight() - fmt.Println("ID", id) - fmt.Println("LastBlockHeight", lastBlockHeight) - - //---------------------------------------------------- - // XXX: start hacking! - //---------------------------------------------------- - // eg. gaia-6001 testnet bug - // We paniced when iterating through the "bypower" keys. - // The following powerKey was there, but the corresponding "trouble" validator did not exist. - // So here we do a binary search on the past states to find when the powerKey first showed up ... - - // operator of the validator the bonds, gets jailed, later unbonds, and then later is still found in the bypower store - trouble := hexToBytes("D3DC0FF59F7C3B548B7AFA365561B87FD0208AF8") - // this is his "bypower" key - powerKey := hexToBytes("05303030303030303030303033FFFFFFFFFFFF4C0C0000FFFED3DC0FF59F7C3B548B7AFA365561B87FD0208AF8") - - topHeight := lastBlockHeight - bottomHeight := int64(0) - checkHeight := topHeight - for { - // load the given version of the state - err = app.LoadVersion(checkHeight, app.keyMain) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - ctx := app.NewContext(true, abci.Header{}) - - // check for the powerkey and the validator from the store - store := ctx.KVStore(app.keyStaking) - res := store.Get(powerKey) - val, _ := app.stakingKeeper.GetValidator(ctx, trouble) - fmt.Println("checking height", checkHeight, res, val) - if res == nil { - bottomHeight = checkHeight - } else { - topHeight = checkHeight - } - checkHeight = (topHeight + bottomHeight) / 2 - } -} - -func base64ToPub(b64 string) ed25519.PubKeyEd25519 { - data, _ := base64.StdEncoding.DecodeString(b64) - var pubKey ed25519.PubKeyEd25519 - copy(pubKey[:], data) - return pubKey - -} - -func hexToBytes(h string) []byte { - trouble, _ := hex.DecodeString(h) - return trouble - -} - -//-------------------------------------------------------------------------------- -// NOTE: This is all copied from gaia/app/app.go -// so we can access internal fields! - -const ( - appName = "GaiaApp" -) - -// default home directories for expected binaries -var ( - DefaultCLIHome = os.ExpandEnv("$HOME/.gaiacli") - DefaultNodeHome = os.ExpandEnv("$HOME/.gaiad") -) - -// Extended ABCI application -type GaiaApp struct { - *bam.BaseApp - cdc *codec.Codec - - // keys to access the substores - keyMain *sdk.KVStoreKey - keyAccount *sdk.KVStoreKey - keyStaking *sdk.KVStoreKey - tkeyStaking *sdk.TransientStoreKey - keySlashing *sdk.KVStoreKey - keyParams *sdk.KVStoreKey - tkeyParams *sdk.TransientStoreKey - - // Manage getting and setting accounts - accountKeeper auth.AccountKeeper - feeCollectionKeeper auth.FeeCollectionKeeper - bankKeeper bank.Keeper - stakingKeeper staking.Keeper - slashingKeeper slashing.Keeper - paramsKeeper params.Keeper -} - -func NewGaiaApp(logger log.Logger, db dbm.DB, baseAppOptions ...func(*bam.BaseApp)) *GaiaApp { - cdc := MakeCodec() - - bApp := bam.NewBaseApp(appName, logger, db, auth.DefaultTxDecoder(cdc), baseAppOptions...) - bApp.SetCommitMultiStoreTracer(os.Stdout) - - // create your application object - var app = &GaiaApp{ - BaseApp: bApp, - cdc: cdc, - keyMain: sdk.NewKVStoreKey(bam.MainStoreKey), - keyAccount: sdk.NewKVStoreKey(auth.StoreKey), - keyStaking: sdk.NewKVStoreKey(staking.StoreKey), - tkeyStaking: sdk.NewTransientStoreKey(staking.TStoreKey), - keySlashing: sdk.NewKVStoreKey(slashing.StoreKey), - keyParams: sdk.NewKVStoreKey(params.StoreKey), - tkeyParams: sdk.NewTransientStoreKey(params.TStoreKey), - } - - app.paramsKeeper = params.NewKeeper(app.cdc, app.keyParams, app.tkeyParams) - - // define the accountKeeper - app.accountKeeper = auth.NewAccountKeeper( - app.cdc, - app.keyAccount, // target store - app.paramsKeeper.Subspace(auth.DefaultParamspace), - auth.ProtoBaseAccount, // prototype - ) - - // add handlers - app.bankKeeper = bank.NewBaseKeeper(app.accountKeeper, app.paramsKeeper.Subspace(bank.DefaultParamspace), bank.DefaultCodespace) - app.stakingKeeper = staking.NewKeeper(app.cdc, app.keyStaking, app.tkeyStaking, app.bankKeeper, app.paramsKeeper.Subspace(staking.DefaultParamspace), staking.DefaultCodespace) - app.slashingKeeper = slashing.NewKeeper(app.cdc, app.keySlashing, app.stakingKeeper, app.paramsKeeper.Subspace(slashing.DefaultParamspace), slashing.DefaultCodespace) - - // register message routes - app.Router(). - AddRoute("bank", bank.NewHandler(app.bankKeeper)). - AddRoute(staking.RouterKey, staking.NewHandler(app.stakingKeeper)) - - // initialize BaseApp - app.SetInitChainer(app.initChainer) - app.SetBeginBlocker(app.BeginBlocker) - app.SetEndBlocker(app.EndBlocker) - app.SetAnteHandler(auth.NewAnteHandler(app.accountKeeper, app.feeCollectionKeeper)) - app.MountStores(app.keyMain, app.keyAccount, app.keyStaking, app.keySlashing, app.keyParams) - app.MountStore(app.tkeyParams, sdk.StoreTypeTransient) - err := app.LoadLatestVersion(app.keyMain) - if err != nil { - cmn.Exit(err.Error()) - } - - app.Seal() - - return app -} - -// custom tx codec -func MakeCodec() *codec.Codec { - var cdc = codec.New() - bank.RegisterCodec(cdc) - staking.RegisterCodec(cdc) - slashing.RegisterCodec(cdc) - auth.RegisterCodec(cdc) - sdk.RegisterCodec(cdc) - codec.RegisterCrypto(cdc) - cdc.Seal() - return cdc -} - -// application updates every end block -func (app *GaiaApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock { - tags := slashing.BeginBlocker(ctx, req, app.slashingKeeper) - - return abci.ResponseBeginBlock{ - Tags: tags.ToKVPairs(), - } -} - -// application updates every end block -// nolint: unparam -func (app *GaiaApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { - validatorUpdates, tags := staking.EndBlocker(ctx, app.stakingKeeper) - - return abci.ResponseEndBlock{ - ValidatorUpdates: validatorUpdates, - Tags: tags, - } -} - -// custom logic for gaia initialization -func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { - stateJSON := req.AppStateBytes - // TODO is this now the whole genesis file? - - var genesisState gaia.GenesisState - err := app.cdc.UnmarshalJSON(stateJSON, &genesisState) - if err != nil { - panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 // return sdk.ErrGenesisParse("").TraceCause(err, "") - } - - // load the accounts - for _, gacc := range genesisState.Accounts { - acc := gacc.ToAccount() - app.accountKeeper.SetAccount(ctx, acc) - } - - // load the initial staking information - validators, err := staking.InitGenesis(ctx, app.stakingKeeper, genesisState.StakingData) - if err != nil { - panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 // return sdk.ErrGenesisParse("").TraceCause(err, "") - } - - slashing.InitGenesis(ctx, app.slashingKeeper, genesisState.SlashingData, genesisState.StakingData.Validators.ToSDKValidators()) - - return abci.ResponseInitChain{ - Validators: validators, - } -} diff --git a/gaia/cmd/gaiadebug/main.go b/gaia/cmd/gaiadebug/main.go deleted file mode 100644 index 095c77a9..00000000 --- a/gaia/cmd/gaiadebug/main.go +++ /dev/null @@ -1,256 +0,0 @@ -package main - -import ( - "bytes" - "encoding/base64" - "encoding/hex" - "encoding/json" - "fmt" - "os" - "strconv" - "strings" - - "github.com/spf13/cobra" - "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/ed25519" - - gaia "github.com/cosmos/cosmos-sdk/cmd/gaia/app" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth" -) - -func init() { - - config := sdk.GetConfig() - config.SetBech32PrefixForAccount(sdk.Bech32PrefixAccAddr, sdk.Bech32PrefixAccPub) - config.SetBech32PrefixForValidator(sdk.Bech32PrefixValAddr, sdk.Bech32PrefixValPub) - config.SetBech32PrefixForConsensusNode(sdk.Bech32PrefixConsAddr, sdk.Bech32PrefixConsPub) - config.Seal() - - rootCmd.AddCommand(txCmd) - rootCmd.AddCommand(pubkeyCmd) - rootCmd.AddCommand(addrCmd) - rootCmd.AddCommand(hackCmd) - rootCmd.AddCommand(rawBytesCmd) -} - -var rootCmd = &cobra.Command{ - Use: "gaiadebug", - Short: "Gaia debug tool", - SilenceUsage: true, -} - -var txCmd = &cobra.Command{ - Use: "tx", - Short: "Decode a gaia tx from hex or base64", - RunE: runTxCmd, -} - -var pubkeyCmd = &cobra.Command{ - Use: "pubkey", - Short: "Decode a pubkey from hex, base64, or bech32", - RunE: runPubKeyCmd, -} - -var addrCmd = &cobra.Command{ - Use: "addr", - Short: "Convert an address between hex and bech32", - RunE: runAddrCmd, -} - -var hackCmd = &cobra.Command{ - Use: "hack", - Short: "Boilerplate to Hack on an existing state by scripting some Go...", - RunE: runHackCmd, -} - -var rawBytesCmd = &cobra.Command{ - Use: "raw-bytes", - Short: "Convert raw bytes output (eg. [10 21 13 255]) to hex", - RunE: runRawBytesCmd, -} - -func runRawBytesCmd(cmd *cobra.Command, args []string) error { - if len(args) != 1 { - return fmt.Errorf("Expected single arg") - } - stringBytes := args[0] - stringBytes = strings.Trim(stringBytes, "[") - stringBytes = strings.Trim(stringBytes, "]") - spl := strings.Split(stringBytes, " ") - - byteArray := []byte{} - for _, s := range spl { - b, err := strconv.Atoi(s) - if err != nil { - return err - } - byteArray = append(byteArray, byte(b)) - } - fmt.Printf("%X\n", byteArray) - return nil -} - -func runPubKeyCmd(cmd *cobra.Command, args []string) error { - if len(args) != 1 { - return fmt.Errorf("Expected single arg") - } - - pubkeyString := args[0] - var pubKeyI crypto.PubKey - - // try hex, then base64, then bech32 - pubkeyBytes, err := hex.DecodeString(pubkeyString) - if err != nil { - var err2 error - pubkeyBytes, err2 = base64.StdEncoding.DecodeString(pubkeyString) - if err2 != nil { - var err3 error - pubKeyI, err3 = sdk.GetAccPubKeyBech32(pubkeyString) - if err3 != nil { - var err4 error - pubKeyI, err4 = sdk.GetValPubKeyBech32(pubkeyString) - - if err4 != nil { - var err5 error - pubKeyI, err5 = sdk.GetConsPubKeyBech32(pubkeyString) - if err5 != nil { - return fmt.Errorf(`Expected hex, base64, or bech32. Got errors: - hex: %v, - base64: %v - bech32 Acc: %v - bech32 Val: %v - bech32 Cons: %v`, - err, err2, err3, err4, err5) - } - - } - } - - } - } - - var pubKey ed25519.PubKeyEd25519 - if pubKeyI == nil { - copy(pubKey[:], pubkeyBytes) - } else { - pubKey = pubKeyI.(ed25519.PubKeyEd25519) - pubkeyBytes = pubKey[:] - } - - cdc := gaia.MakeCodec() - pubKeyJSONBytes, err := cdc.MarshalJSON(pubKey) - if err != nil { - return err - } - accPub, err := sdk.Bech32ifyAccPub(pubKey) - if err != nil { - return err - } - valPub, err := sdk.Bech32ifyValPub(pubKey) - if err != nil { - return err - } - - consenusPub, err := sdk.Bech32ifyConsPub(pubKey) - if err != nil { - return err - } - fmt.Println("Address:", pubKey.Address()) - fmt.Printf("Hex: %X\n", pubkeyBytes) - fmt.Println("JSON (base64):", string(pubKeyJSONBytes)) - fmt.Println("Bech32 Acc:", accPub) - fmt.Println("Bech32 Validator Operator:", valPub) - fmt.Println("Bech32 Validator Consensus:", consenusPub) - return nil -} - -func runAddrCmd(cmd *cobra.Command, args []string) error { - if len(args) != 1 { - return fmt.Errorf("Expected single arg") - } - - addrString := args[0] - var addr []byte - - // try hex, then bech32 - var err error - addr, err = hex.DecodeString(addrString) - if err != nil { - var err2 error - addr, err2 = sdk.AccAddressFromBech32(addrString) - if err2 != nil { - var err3 error - addr, err3 = sdk.ValAddressFromBech32(addrString) - - if err3 != nil { - return fmt.Errorf(`Expected hex or bech32. Got errors: - hex: %v, - bech32 acc: %v - bech32 val: %v - `, err, err2, err3) - - } - } - } - - accAddr := sdk.AccAddress(addr) - valAddr := sdk.ValAddress(addr) - - fmt.Println("Address:", addr) - fmt.Printf("Address (hex): %X\n", addr) - fmt.Printf("Bech32 Acc: %s\n", accAddr) - fmt.Printf("Bech32 Val: %s\n", valAddr) - return nil -} - -func runTxCmd(cmd *cobra.Command, args []string) error { - if len(args) != 1 { - return fmt.Errorf("Expected single arg") - } - - txString := args[0] - - // try hex, then base64 - txBytes, err := hex.DecodeString(txString) - if err != nil { - var err2 error - txBytes, err2 = base64.StdEncoding.DecodeString(txString) - if err2 != nil { - return fmt.Errorf(`Expected hex or base64. Got errors: - hex: %v, - base64: %v - `, err, err2) - } - } - - var tx = auth.StdTx{} - cdc := gaia.MakeCodec() - - err = cdc.UnmarshalBinaryLengthPrefixed(txBytes, &tx) - if err != nil { - return err - } - - bz, err := cdc.MarshalJSON(tx) - if err != nil { - return err - } - - buf := bytes.NewBuffer([]byte{}) - err = json.Indent(buf, bz, "", " ") - if err != nil { - return err - } - - fmt.Println(buf.String()) - return nil -} - -func main() { - err := rootCmd.Execute() - if err != nil { - os.Exit(1) - } - os.Exit(0) -} diff --git a/gaia/cmd/gaiakeyutil/main.go b/gaia/cmd/gaiakeyutil/main.go deleted file mode 100644 index 46eefc69..00000000 --- a/gaia/cmd/gaiakeyutil/main.go +++ /dev/null @@ -1,59 +0,0 @@ -package main - -import ( - "encoding/hex" - "fmt" - "os" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/tendermint/tendermint/libs/bech32" -) - -var bech32Prefixes = []string{ - sdk.Bech32PrefixAccAddr, - sdk.Bech32PrefixAccPub, - sdk.Bech32PrefixValAddr, - sdk.Bech32PrefixValPub, - sdk.Bech32PrefixConsAddr, - sdk.Bech32PrefixConsPub, -} - -func main() { - if len(os.Args) < 2 { - fmt.Println("Must specify an input string") - } - arg := os.Args[1] - runFromBech32(arg) - runFromHex(arg) -} - -// Print info from bech32. -func runFromBech32(bech32str string) { - hrp, bz, err := bech32.DecodeAndConvert(bech32str) - if err != nil { - fmt.Println("Not a valid bech32 string") - return - } - fmt.Println("Bech32 parse:") - fmt.Printf("Human readible part: %v\nBytes (hex): %X\n", - hrp, - bz, - ) -} - -func runFromHex(hexaddr string) { - bz, err := hex.DecodeString(hexaddr) - if err != nil { - fmt.Println("Not a valid hex string") - return - } - fmt.Println("Hex parse:") - fmt.Println("Bech32 formats:") - for _, prefix := range bech32Prefixes { - bech32Addr, err := bech32.ConvertAndEncode(prefix, bz) - if err != nil { - panic(err) - } - fmt.Println(" - " + bech32Addr) - } -} diff --git a/gaia/cmd/gaiareplay/main.go b/gaia/cmd/gaiareplay/main.go deleted file mode 100644 index d41a65c7..00000000 --- a/gaia/cmd/gaiareplay/main.go +++ /dev/null @@ -1,206 +0,0 @@ -package main - -import ( - "fmt" - "io" - "os" - "path/filepath" - "time" - - "github.com/cosmos/cosmos-sdk/store" - - cpm "github.com/otiai10/copy" - "github.com/spf13/cobra" - - abci "github.com/tendermint/tendermint/abci/types" - bcm "github.com/tendermint/tendermint/blockchain" - cmn "github.com/tendermint/tendermint/libs/common" - "github.com/tendermint/tendermint/proxy" - tmsm "github.com/tendermint/tendermint/state" - tm "github.com/tendermint/tendermint/types" - - "github.com/cosmos/cosmos-sdk/baseapp" - "github.com/cosmos/cosmos-sdk/cmd/gaia/app" - "github.com/cosmos/cosmos-sdk/server" - sdk "github.com/cosmos/cosmos-sdk/types" -) - -var ( - rootDir string -) - -var rootCmd = &cobra.Command{ - Use: "gaiareplay", - Short: "Replay gaia transactions", - Run: func(cmd *cobra.Command, args []string) { - run(rootDir) - }, -} - -func init() { - // cobra.OnInitialize(initConfig) - rootCmd.PersistentFlags().StringVar(&rootDir, "root", "r", "root dir") -} - -func main() { - if err := rootCmd.Execute(); err != nil { - fmt.Println(err) - os.Exit(1) - } -} - -func run(rootDir string) { - - if false { - // Copy the rootDir to a new directory, to preserve the old one. - fmt.Println("Copying rootdir over") - oldRootDir := rootDir - rootDir = oldRootDir + "_replay" - if cmn.FileExists(rootDir) { - cmn.Exit(fmt.Sprintf("temporary copy dir %v already exists", rootDir)) - } - err := cpm.Copy(oldRootDir, rootDir) - if err != nil { - panic(err) - } - } - - configDir := filepath.Join(rootDir, "config") - dataDir := filepath.Join(rootDir, "data") - ctx := server.NewDefaultContext() - - // App DB - // appDB := dbm.NewMemDB() - fmt.Println("Opening app database") - appDB, err := sdk.NewLevelDB("application", dataDir) - if err != nil { - panic(err) - } - - // TM DB - // tmDB := dbm.NewMemDB() - fmt.Println("Opening tendermint state database") - tmDB, err := sdk.NewLevelDB("state", dataDir) - if err != nil { - panic(err) - } - - // Blockchain DB - fmt.Println("Opening blockstore database") - bcDB, err := sdk.NewLevelDB("blockstore", dataDir) - if err != nil { - panic(err) - } - - // TraceStore - var traceStoreWriter io.Writer - var traceStoreDir = filepath.Join(dataDir, "trace.log") - traceStoreWriter, err = os.OpenFile( - traceStoreDir, - os.O_WRONLY|os.O_APPEND|os.O_CREATE, - 0666, - ) - if err != nil { - panic(err) - } - - // Application - fmt.Println("Creating application") - myapp := app.NewGaiaApp( - ctx.Logger, appDB, traceStoreWriter, true, uint(1), - baseapp.SetPruning(store.PruneEverything), // nothing - ) - - // Genesis - var genDocPath = filepath.Join(configDir, "genesis.json") - genDoc, err := tm.GenesisDocFromFile(genDocPath) - if err != nil { - panic(err) - } - genState, err := tmsm.MakeGenesisState(genDoc) - if err != nil { - panic(err) - } - // tmsm.SaveState(tmDB, genState) - - cc := proxy.NewLocalClientCreator(myapp) - proxyApp := proxy.NewAppConns(cc) - err = proxyApp.Start() - if err != nil { - panic(err) - } - defer func() { - _ = proxyApp.Stop() - }() - - state := tmsm.LoadState(tmDB) - if state.LastBlockHeight == 0 { - // Send InitChain msg - fmt.Println("Sending InitChain msg") - validators := tm.TM2PB.ValidatorUpdates(genState.Validators) - csParams := tm.TM2PB.ConsensusParams(genDoc.ConsensusParams) - req := abci.RequestInitChain{ - Time: genDoc.GenesisTime, - ChainId: genDoc.ChainID, - ConsensusParams: csParams, - Validators: validators, - AppStateBytes: genDoc.AppState, - } - res, err := proxyApp.Consensus().InitChainSync(req) - if err != nil { - panic(err) - } - newValidatorz, err := tm.PB2TM.ValidatorUpdates(res.Validators) - if err != nil { - panic(err) - } - newValidators := tm.NewValidatorSet(newValidatorz) - - // Take the genesis state. - state = genState - state.Validators = newValidators - state.NextValidators = newValidators - } - - // Create executor - fmt.Println("Creating block executor") - blockExec := tmsm.NewBlockExecutor(tmDB, ctx.Logger, proxyApp.Consensus(), - tmsm.MockMempool{}, tmsm.MockEvidencePool{}) - - // Create block store - fmt.Println("Creating block store") - blockStore := bcm.NewBlockStore(bcDB) - - tz := []time.Duration{0, 0, 0} - for i := int(state.LastBlockHeight) + 1; ; i++ { - fmt.Println("Running block ", i) - t1 := time.Now() - - // Apply block - fmt.Printf("loading and applying block %d\n", i) - blockmeta := blockStore.LoadBlockMeta(int64(i)) - if blockmeta == nil { - fmt.Printf("Couldn't find block meta %d... done?\n", i) - return - } - block := blockStore.LoadBlock(int64(i)) - if block == nil { - panic(fmt.Sprintf("couldn't find block %d", i)) - } - - t2 := time.Now() - - state, err = blockExec.ApplyBlock(state, blockmeta.BlockID, block) - if err != nil { - panic(err) - } - - t3 := time.Now() - tz[0] += t2.Sub(t1) - tz[1] += t3.Sub(t2) - - fmt.Printf("new app hash: %X\n", state.AppHash) - fmt.Println(tz) - } - -} diff --git a/gaia/testnets/README.md b/gaia/testnets/README.md deleted file mode 100644 index e64db9f7..00000000 --- a/gaia/testnets/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# DEPRECATED - -The content of this file was moved to the `/docs` folder and is hosted on the -[website](https://cosmos.network/docs/getting-started/full-node.html#run-a-full-node). - -The rest of this folder was moved to the [testnets -repo](https://github.com/cosmos/testnets). diff --git a/gaia/testnets/STATUS.md b/gaia/testnets/STATUS.md deleted file mode 100644 index 4db42978..00000000 --- a/gaia/testnets/STATUS.md +++ /dev/null @@ -1,132 +0,0 @@ -# DEPRECATED - -See [testnets repo](https://github.com/cosmos/testnets). - -## *July 22, 2018, 5:30 EST* - Gaia-7001 Consensus Failure - -- [Consensus Failure at Block 24570](https://github.com/cosmos/cosmos-sdk/issues/1787) - - -## *July 17, 2018, 4:00 EST* - New Testnet Gaia-7001 - -- New testnet with fixes for the genesis file -- Increased max validators to 128 - -## *July 17, 2018, 3:00 EST* - Gaia-7000 consensus failure - -- Misconfiguration in the genesis file led to a consensus failure -- New genesis file for gaia-7001 will be up soon - -## *July 17, 2018, 2:40 EST* - Gaia-7000 is making blocks! - -- Gaia-7000 is live and making blocks! - -## *July 16, 2018, 17:00 EST* - New Testnet Gaia-7000 - -- Gaia-7000 is up! -- 108 validators in the genesis.json file. - -## *July 2, 2018, 1:00 EST* - Gaia-6002 slashing failure - -- Gaia-6002 has been halted due to a slashing issue. -- The team is taking its time to look into this Gaia-7000 will be introduced this week. - -## *June 13, 2018, 17:00 EST* - Gaia-6002 is making blocks! - -- Gaia-6002 is live and making blocks -- Absent validators have been slashed and jailed -- Currently live with 17 validators - -## *June 13, 2018, 4:30 EST* - New Testnet Gaia-6002 - -- After fixing bugs from gaia-6001, especially [issue - #1197](https://github.com/cosmos/cosmos-sdk/issues/1197), we are announcing a - new testnet, Gaia-6002 -- Gaia-6002 has the same genesis file as Gaia-6001, just with the chain-id - updated -- Update from previous testnet [here](https://github.com/cosmos/cosmos-sdk/tree/master/cmd/gaia/testnets#upgrading-from-previous-testnet) - -## *June 13, 2018, 4:30 EST* - New Release - -- Released gaia - [v0.19.0](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.19.0) -- Includes various bug-fixes for staking found on Gaia-6001 - -## *June 13, 2018, 2:30 EST* - Published Postmortem of Gaia-6001 failure - -- A bug in the design of the staking data model caused a sanity check to fail -- Full writeup - [here](https://github.com/cosmos/cosmos-sdk/issues/1197#issuecomment-396823021) - -## *June 10, 2018, 8:30 EST* - Gaia-6001 consensus failure - -- Validator unbonding and revocation activity caused a consensus failure -- There is a bug in the staking module that must be fixed -- The team is taking its time to look into this and release a fix following a - proper protocol for hotfix upgrades to the testnet -- Please stay tuned! - -## *June 9, 2018, 14:00 EST* - New Release - -- Released gaia - [v0.18.0](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.18.0) with - update for Tendermint - [v0.20.0](https://github.com/tendermint/tendermint/releases/tag/v0.20.0) -- Includes bug fix for declaring candidacy from the command line - -## *June 8, 2018, 23:30 EST* - Gaia-6001 is making blocks - -- +2/3 of the voting power is finally online for Gaia-6001 and it is making - blocks! -- This is a momentous achievement - a successful asynchronous decentralized - testnet launch -- Congrats everyone! - -## *June 8, 2018, 12:00 EST* - New Testnet Gaia-6001 - -- After some confusion around testnet deployment and a contention testnet - hardfork, a new genesis file and network was released for `gaia-6001` - -## *June 7, 2018, 9:00 EST* - New Testnet Gaia-6000 - -- Released a new `genesis.json` file for `gaia-6000` -- Initial validators include those that were most active in - the gaia-5001 testnet -- Join the network via gaia `v0.18.0-rc0` - -## *June 5, 2018, 21:00 EST* - New Release - -- Released gaia - [v0.17.5](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.17.5) - with update for Tendermint - [v0.19.9](https://github.com/tendermint/tendermint/releases/tag/v0.19.9) -- Fixes many bugs! - - evidence gossipping - - mempool deadlock - - WAL panic - - memory leak -- Please update to this to put a stop to the rampant invalid evidence gossiping - :) - -## *May 31, 2018, 14:00 EST* - New Release - -- Released gaia - [v0.17.4](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.17.4) with update for Tendermint v0.19.7 -- Fixes a WAL bug and some more -- Please update to this if you have trouble restarting a node - -## *May 31, 2018, 2:00 EST* - Testnet Halt - -- A validator equivocated last week and Evidence is being rampantly gossipped -- Peers that can't process the evidence (either too far behind or too far ahead) are disconnecting from the peers that - sent it, causing high peer turn-over -- The high peer turn-over may be causing a memory-leak, resulting in some nodes - crashing and the testnet halting -- We need to fix some issues in the EvidenceReactor to address this and also - investigate the possible memory-leak - -## *May 29, 2018* - New Release - -- Released v0.17.3 with update for Tendermint v0.19.6 -- Fixes fast-sync bug -- Please update to this to sync with the testnet