mirror of
				https://github.com/0glabs/0g-chain.git
				synced 2025-10-31 21:47:27 +00:00 
			
		
		
		
	
						commit
						3ff2637431
					
				
							
								
								
									
										23
									
								
								Gopkg.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										23
									
								
								Gopkg.lock
									
									
									
										generated
									
									
									
								
							| @ -48,7 +48,7 @@ | |||||||
|   revision = "d4cc87b860166d00d6b5b9e0d3b3d71d6088d4d4" |   revision = "d4cc87b860166d00d6b5b9e0d3b3d71d6088d4d4" | ||||||
| 
 | 
 | ||||||
| [[projects]] | [[projects]] | ||||||
|   digest = "1:7f6e80c9a48014e57211353a9a82d12088f9dc85f564b6a70674bbc1d5abc34e" |   digest = "1:485c3fd6d387a850672e86b89eabf32d0363890652c1b499898c925a5e8a02ce" | ||||||
|   name = "github.com/cosmos/cosmos-sdk" |   name = "github.com/cosmos/cosmos-sdk" | ||||||
|   packages = [ |   packages = [ | ||||||
|     "baseapp", |     "baseapp", | ||||||
| @ -66,21 +66,26 @@ | |||||||
|     "server", |     "server", | ||||||
|     "server/config", |     "server/config", | ||||||
|     "store", |     "store", | ||||||
|  |     "tests", | ||||||
|     "types", |     "types", | ||||||
|     "version", |     "version", | ||||||
|     "wire", |     "wire", | ||||||
|     "x/auth", |     "x/auth", | ||||||
|     "x/auth/client/cli", |     "x/auth/client/cli", | ||||||
|     "x/auth/client/context", |     "x/auth/client/context", | ||||||
|  |     "x/auth/client/rest", | ||||||
|     "x/bank", |     "x/bank", | ||||||
|     "x/bank/client", |     "x/bank/client", | ||||||
|     "x/bank/client/cli", |     "x/bank/client/cli", | ||||||
|  |     "x/bank/client/rest", | ||||||
|     "x/mock", |     "x/mock", | ||||||
|     "x/params", |     "x/params", | ||||||
|     "x/slashing", |     "x/slashing", | ||||||
|     "x/slashing/client/cli", |     "x/slashing/client/cli", | ||||||
|  |     "x/slashing/client/rest", | ||||||
|     "x/stake", |     "x/stake", | ||||||
|     "x/stake/client/cli", |     "x/stake/client/cli", | ||||||
|  |     "x/stake/client/rest", | ||||||
|     "x/stake/keeper", |     "x/stake/keeper", | ||||||
|     "x/stake/tags", |     "x/stake/tags", | ||||||
|     "x/stake/types", |     "x/stake/types", | ||||||
| @ -673,34 +678,50 @@ | |||||||
|     "github.com/cosmos/cosmos-sdk/client/rpc", |     "github.com/cosmos/cosmos-sdk/client/rpc", | ||||||
|     "github.com/cosmos/cosmos-sdk/client/tx", |     "github.com/cosmos/cosmos-sdk/client/tx", | ||||||
|     "github.com/cosmos/cosmos-sdk/client/utils", |     "github.com/cosmos/cosmos-sdk/client/utils", | ||||||
|  |     "github.com/cosmos/cosmos-sdk/crypto/keys", | ||||||
|     "github.com/cosmos/cosmos-sdk/server", |     "github.com/cosmos/cosmos-sdk/server", | ||||||
|     "github.com/cosmos/cosmos-sdk/server/config", |     "github.com/cosmos/cosmos-sdk/server/config", | ||||||
|  |     "github.com/cosmos/cosmos-sdk/tests", | ||||||
|     "github.com/cosmos/cosmos-sdk/types", |     "github.com/cosmos/cosmos-sdk/types", | ||||||
|     "github.com/cosmos/cosmos-sdk/version", |     "github.com/cosmos/cosmos-sdk/version", | ||||||
|     "github.com/cosmos/cosmos-sdk/wire", |     "github.com/cosmos/cosmos-sdk/wire", | ||||||
|     "github.com/cosmos/cosmos-sdk/x/auth", |     "github.com/cosmos/cosmos-sdk/x/auth", | ||||||
|     "github.com/cosmos/cosmos-sdk/x/auth/client/cli", |     "github.com/cosmos/cosmos-sdk/x/auth/client/cli", | ||||||
|     "github.com/cosmos/cosmos-sdk/x/auth/client/context", |     "github.com/cosmos/cosmos-sdk/x/auth/client/context", | ||||||
|  |     "github.com/cosmos/cosmos-sdk/x/auth/client/rest", | ||||||
|     "github.com/cosmos/cosmos-sdk/x/bank", |     "github.com/cosmos/cosmos-sdk/x/bank", | ||||||
|     "github.com/cosmos/cosmos-sdk/x/bank/client/cli", |     "github.com/cosmos/cosmos-sdk/x/bank/client/cli", | ||||||
|  |     "github.com/cosmos/cosmos-sdk/x/bank/client/rest", | ||||||
|     "github.com/cosmos/cosmos-sdk/x/mock", |     "github.com/cosmos/cosmos-sdk/x/mock", | ||||||
|     "github.com/cosmos/cosmos-sdk/x/params", |     "github.com/cosmos/cosmos-sdk/x/params", | ||||||
|     "github.com/cosmos/cosmos-sdk/x/slashing", |     "github.com/cosmos/cosmos-sdk/x/slashing", | ||||||
|     "github.com/cosmos/cosmos-sdk/x/slashing/client/cli", |     "github.com/cosmos/cosmos-sdk/x/slashing/client/cli", | ||||||
|  |     "github.com/cosmos/cosmos-sdk/x/slashing/client/rest", | ||||||
|     "github.com/cosmos/cosmos-sdk/x/stake", |     "github.com/cosmos/cosmos-sdk/x/stake", | ||||||
|     "github.com/cosmos/cosmos-sdk/x/stake/client/cli", |     "github.com/cosmos/cosmos-sdk/x/stake/client/cli", | ||||||
|  |     "github.com/cosmos/cosmos-sdk/x/stake/client/rest", | ||||||
|  |     "github.com/gorilla/mux", | ||||||
|     "github.com/pkg/errors", |     "github.com/pkg/errors", | ||||||
|     "github.com/spf13/cobra", |     "github.com/spf13/cobra", | ||||||
|     "github.com/spf13/pflag", |     "github.com/spf13/pflag", | ||||||
|     "github.com/spf13/viper", |     "github.com/spf13/viper", | ||||||
|     "github.com/stretchr/testify/assert", |     "github.com/stretchr/testify/assert", | ||||||
|  |     "github.com/stretchr/testify/require", | ||||||
|  |     "github.com/tendermint/go-amino", | ||||||
|     "github.com/tendermint/tendermint/abci/types", |     "github.com/tendermint/tendermint/abci/types", | ||||||
|  |     "github.com/tendermint/tendermint/config", | ||||||
|     "github.com/tendermint/tendermint/crypto", |     "github.com/tendermint/tendermint/crypto", | ||||||
|     "github.com/tendermint/tendermint/crypto/ed25519", |     "github.com/tendermint/tendermint/crypto/ed25519", | ||||||
|     "github.com/tendermint/tendermint/libs/cli", |     "github.com/tendermint/tendermint/libs/cli", | ||||||
|     "github.com/tendermint/tendermint/libs/common", |     "github.com/tendermint/tendermint/libs/common", | ||||||
|     "github.com/tendermint/tendermint/libs/db", |     "github.com/tendermint/tendermint/libs/db", | ||||||
|     "github.com/tendermint/tendermint/libs/log", |     "github.com/tendermint/tendermint/libs/log", | ||||||
|  |     "github.com/tendermint/tendermint/node", | ||||||
|  |     "github.com/tendermint/tendermint/p2p", | ||||||
|  |     "github.com/tendermint/tendermint/privval", | ||||||
|  |     "github.com/tendermint/tendermint/proxy", | ||||||
|  |     "github.com/tendermint/tendermint/rpc/core/types", | ||||||
|  |     "github.com/tendermint/tendermint/rpc/lib/server", | ||||||
|     "github.com/tendermint/tendermint/types", |     "github.com/tendermint/tendermint/types", | ||||||
|   ] |   ] | ||||||
|   solver-name = "gps-cdcl" |   solver-name = "gps-cdcl" | ||||||
|  | |||||||
| @ -22,7 +22,7 @@ import ( | |||||||
| 	paychancmd "github.com/kava-labs/kava/internal/x/paychan/client/cli" | 	paychancmd "github.com/kava-labs/kava/internal/x/paychan/client/cli" | ||||||
| 
 | 
 | ||||||
| 	"github.com/kava-labs/kava/internal/app" | 	"github.com/kava-labs/kava/internal/app" | ||||||
| 	//"github.com/kava-labs/kava/internal/lcd"
 | 	"github.com/kava-labs/kava/internal/lcd" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var ( | var ( | ||||||
| @ -59,8 +59,7 @@ func main() { | |||||||
| 
 | 
 | ||||||
| 	advancedCmd.AddCommand( | 	advancedCmd.AddCommand( | ||||||
| 		tendermintCmd, | 		tendermintCmd, | ||||||
| 		//ibcCmd,
 | 		lcd.ServeCommand(cdc), | ||||||
| 		//lcd.ServeCommand(cdc),
 |  | ||||||
| 	) | 	) | ||||||
| 	rootCmd.AddCommand( | 	rootCmd.AddCommand( | ||||||
| 		advancedCmd, | 		advancedCmd, | ||||||
|  | |||||||
| @ -1,27 +1,24 @@ | |||||||
| package lcd | package lcd | ||||||
| 
 | 
 | ||||||
| /* |  | ||||||
| import ( | import ( | ||||||
| 	"net/http" |  | ||||||
| 	//"encoding/hex"
 |  | ||||||
| 	"encoding/base64" | 	"encoding/base64" | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
|  | 	"net/http" | ||||||
| 
 | 
 | ||||||
| 	"github.com/cosmos/cosmos-sdk/client/context" | 	"github.com/cosmos/cosmos-sdk/client/context" | ||||||
| 	"github.com/cosmos/cosmos-sdk/wire" | 	"github.com/cosmos/cosmos-sdk/wire" | ||||||
| 	"github.com/cosmos/cosmos-sdk/x/auth" | 	"github.com/cosmos/cosmos-sdk/x/auth" | ||||||
| ) | ) | ||||||
| */ |  | ||||||
| 
 | 
 | ||||||
| type TxBody struct { | type txBody struct { | ||||||
| 	TxBase64 string `json:"txbase64"` | 	TxBase64 string `json:"txbase64"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Decode a tx from base64 into json
 | // Decode a tx from base64 into json
 | ||||||
| func DecodeTxRequestHandlerFn(ctx context.CoreContext, cdc *wire.Codec) http.HandlerFunc { | func DecodeTxRequestHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc { | ||||||
| 	return func(w http.ResponseWriter, r *http.Request) { | 	return func(w http.ResponseWriter, r *http.Request) { | ||||||
| 		// get the input base64 string
 | 		// get the input base64 string
 | ||||||
| 		var m TxBody | 		var m txBody | ||||||
| 		decoder := json.NewDecoder(r.Body) | 		decoder := json.NewDecoder(r.Body) | ||||||
| 		err := decoder.Decode(&m) | 		err := decoder.Decode(&m) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
|  | |||||||
							
								
								
									
										695
									
								
								internal/lcd/lcd_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										695
									
								
								internal/lcd/lcd_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,695 @@ | |||||||
|  | // Copyright 2016 All in Bits, inc
 | ||||||
|  | // Modifications copyright 2018 Kava Labs
 | ||||||
|  | package lcd | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"encoding/hex" | ||||||
|  | 	"fmt" | ||||||
|  | 	"net/http" | ||||||
|  | 	"regexp" | ||||||
|  | 	"testing" | ||||||
|  | 	"time" | ||||||
|  | 
 | ||||||
|  | 	"github.com/cosmos/cosmos-sdk/client/tx" | ||||||
|  | 
 | ||||||
|  | 	"github.com/spf13/viper" | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
|  | 	"github.com/stretchr/testify/require" | ||||||
|  | 
 | ||||||
|  | 	cryptoKeys "github.com/cosmos/cosmos-sdk/crypto/keys" | ||||||
|  | 	p2p "github.com/tendermint/tendermint/p2p" | ||||||
|  | 	ctypes "github.com/tendermint/tendermint/rpc/core/types" | ||||||
|  | 
 | ||||||
|  | 	client "github.com/cosmos/cosmos-sdk/client" | ||||||
|  | 	keys "github.com/cosmos/cosmos-sdk/client/keys" | ||||||
|  | 	rpc "github.com/cosmos/cosmos-sdk/client/rpc" | ||||||
|  | 	tests "github.com/cosmos/cosmos-sdk/tests" | ||||||
|  | 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||||
|  | 	"github.com/cosmos/cosmos-sdk/wire" | ||||||
|  | 	"github.com/cosmos/cosmos-sdk/x/auth" | ||||||
|  | 	"github.com/cosmos/cosmos-sdk/x/slashing" | ||||||
|  | 	"github.com/cosmos/cosmos-sdk/x/stake" | ||||||
|  | 	"github.com/cosmos/cosmos-sdk/x/stake/client/rest" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func init() { | ||||||
|  | 	cryptoKeys.BcryptSecurityParameter = 1 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestKeys(t *testing.T) { | ||||||
|  | 	name, password := "test", "1234567890" | ||||||
|  | 	addr, seed := CreateAddr(t, "test", password, GetKeyBase(t)) | ||||||
|  | 	cleanup, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}) | ||||||
|  | 	defer cleanup() | ||||||
|  | 
 | ||||||
|  | 	// get seed
 | ||||||
|  | 	// TODO Do we really need this endpoint?
 | ||||||
|  | 	res, body := Request(t, port, "GET", "/keys/seed", nil) | ||||||
|  | 	require.Equal(t, http.StatusOK, res.StatusCode, body) | ||||||
|  | 	reg, err := regexp.Compile(`([a-z]+ ){12}`) | ||||||
|  | 	require.Nil(t, err) | ||||||
|  | 	match := reg.MatchString(seed) | ||||||
|  | 	require.True(t, match, "Returned seed has wrong format", seed) | ||||||
|  | 
 | ||||||
|  | 	newName := "test_newname" | ||||||
|  | 	newPassword := "0987654321" | ||||||
|  | 
 | ||||||
|  | 	// add key
 | ||||||
|  | 	jsonStr := []byte(fmt.Sprintf(`{"name":"%s", "password":"%s", "seed":"%s"}`, newName, newPassword, seed)) | ||||||
|  | 	res, body = Request(t, port, "POST", "/keys", jsonStr) | ||||||
|  | 
 | ||||||
|  | 	require.Equal(t, http.StatusOK, res.StatusCode, body) | ||||||
|  | 	var resp keys.KeyOutput | ||||||
|  | 	err = wire.Cdc.UnmarshalJSON([]byte(body), &resp) | ||||||
|  | 	require.Nil(t, err, body) | ||||||
|  | 
 | ||||||
|  | 	addr2Bech32 := resp.Address.String() | ||||||
|  | 	_, err = sdk.AccAddressFromBech32(addr2Bech32) | ||||||
|  | 	require.NoError(t, err, "Failed to return a correct bech32 address") | ||||||
|  | 
 | ||||||
|  | 	// test if created account is the correct account
 | ||||||
|  | 	expectedInfo, _ := GetKeyBase(t).CreateKey(newName, seed, newPassword) | ||||||
|  | 	expectedAccount := sdk.AccAddress(expectedInfo.GetPubKey().Address().Bytes()) | ||||||
|  | 	assert.Equal(t, expectedAccount.String(), addr2Bech32) | ||||||
|  | 
 | ||||||
|  | 	// existing keys
 | ||||||
|  | 	res, body = Request(t, port, "GET", "/keys", nil) | ||||||
|  | 	require.Equal(t, http.StatusOK, res.StatusCode, body) | ||||||
|  | 	var m [2]keys.KeyOutput | ||||||
|  | 	err = cdc.UnmarshalJSON([]byte(body), &m) | ||||||
|  | 	require.Nil(t, err) | ||||||
|  | 
 | ||||||
|  | 	addrBech32 := addr.String() | ||||||
|  | 
 | ||||||
|  | 	require.Equal(t, name, m[0].Name, "Did not serve keys name correctly") | ||||||
|  | 	require.Equal(t, addrBech32, m[0].Address.String(), "Did not serve keys Address correctly") | ||||||
|  | 	require.Equal(t, newName, m[1].Name, "Did not serve keys name correctly") | ||||||
|  | 	require.Equal(t, addr2Bech32, m[1].Address.String(), "Did not serve keys Address correctly") | ||||||
|  | 
 | ||||||
|  | 	// select key
 | ||||||
|  | 	keyEndpoint := fmt.Sprintf("/keys/%s", newName) | ||||||
|  | 	res, body = Request(t, port, "GET", keyEndpoint, nil) | ||||||
|  | 	require.Equal(t, http.StatusOK, res.StatusCode, body) | ||||||
|  | 	var m2 keys.KeyOutput | ||||||
|  | 	err = cdc.UnmarshalJSON([]byte(body), &m2) | ||||||
|  | 	require.Nil(t, err) | ||||||
|  | 
 | ||||||
|  | 	require.Equal(t, newName, m2.Name, "Did not serve keys name correctly") | ||||||
|  | 	require.Equal(t, addr2Bech32, m2.Address.String(), "Did not serve keys Address correctly") | ||||||
|  | 
 | ||||||
|  | 	// update key
 | ||||||
|  | 	jsonStr = []byte(fmt.Sprintf(`{ | ||||||
|  | 		"old_password":"%s", | ||||||
|  | 		"new_password":"12345678901" | ||||||
|  | 	}`, newPassword)) | ||||||
|  | 
 | ||||||
|  | 	res, body = Request(t, port, "PUT", keyEndpoint, jsonStr) | ||||||
|  | 	require.Equal(t, http.StatusOK, res.StatusCode, body) | ||||||
|  | 
 | ||||||
|  | 	// here it should say unauthorized as we changed the password before
 | ||||||
|  | 	res, body = Request(t, port, "PUT", keyEndpoint, jsonStr) | ||||||
|  | 	require.Equal(t, http.StatusUnauthorized, res.StatusCode, body) | ||||||
|  | 
 | ||||||
|  | 	// delete key
 | ||||||
|  | 	jsonStr = []byte(`{"password":"12345678901"}`) | ||||||
|  | 	res, body = Request(t, port, "DELETE", keyEndpoint, jsonStr) | ||||||
|  | 	require.Equal(t, http.StatusOK, res.StatusCode, body) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestVersion(t *testing.T) { | ||||||
|  | 	cleanup, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{}) | ||||||
|  | 	defer cleanup() | ||||||
|  | 
 | ||||||
|  | 	// node info
 | ||||||
|  | 	res, body := Request(t, port, "GET", "/version", nil) | ||||||
|  | 	require.Equal(t, http.StatusOK, res.StatusCode, body) | ||||||
|  | 
 | ||||||
|  | 	reg, err := regexp.Compile(`\d+\.\d+\.\d+(-dev)?`) | ||||||
|  | 	require.Nil(t, err) | ||||||
|  | 	match := reg.MatchString(body) | ||||||
|  | 	require.True(t, match, body) | ||||||
|  | 
 | ||||||
|  | 	// node info
 | ||||||
|  | 	res, body = Request(t, port, "GET", "/node_version", nil) | ||||||
|  | 	require.Equal(t, http.StatusOK, res.StatusCode, body) | ||||||
|  | 
 | ||||||
|  | 	reg, err = regexp.Compile(`\d+\.\d+\.\d+(-dev)?`) | ||||||
|  | 	require.Nil(t, err) | ||||||
|  | 	match = reg.MatchString(body) | ||||||
|  | 	require.True(t, match, body) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestNodeStatus(t *testing.T) { | ||||||
|  | 	cleanup, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{}) | ||||||
|  | 	defer cleanup() | ||||||
|  | 
 | ||||||
|  | 	// node info
 | ||||||
|  | 	res, body := Request(t, port, "GET", "/node_info", nil) | ||||||
|  | 	require.Equal(t, http.StatusOK, res.StatusCode, body) | ||||||
|  | 
 | ||||||
|  | 	var nodeInfo p2p.NodeInfo | ||||||
|  | 	err := cdc.UnmarshalJSON([]byte(body), &nodeInfo) | ||||||
|  | 	require.Nil(t, err, "Couldn't parse node info") | ||||||
|  | 
 | ||||||
|  | 	require.NotEqual(t, p2p.NodeInfo{}, nodeInfo, "res: %v", res) | ||||||
|  | 
 | ||||||
|  | 	// syncing
 | ||||||
|  | 	res, body = Request(t, port, "GET", "/syncing", nil) | ||||||
|  | 	require.Equal(t, http.StatusOK, res.StatusCode, body) | ||||||
|  | 
 | ||||||
|  | 	// we expect that there is no other node running so the syncing state is "false"
 | ||||||
|  | 	require.Equal(t, "false", body) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestBlock(t *testing.T) { | ||||||
|  | 	cleanup, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{}) | ||||||
|  | 	defer cleanup() | ||||||
|  | 
 | ||||||
|  | 	var resultBlock ctypes.ResultBlock | ||||||
|  | 
 | ||||||
|  | 	res, body := Request(t, port, "GET", "/blocks/latest", nil) | ||||||
|  | 	require.Equal(t, http.StatusOK, res.StatusCode, body) | ||||||
|  | 
 | ||||||
|  | 	err := cdc.UnmarshalJSON([]byte(body), &resultBlock) | ||||||
|  | 	require.Nil(t, err, "Couldn't parse block") | ||||||
|  | 
 | ||||||
|  | 	require.NotEqual(t, ctypes.ResultBlock{}, resultBlock) | ||||||
|  | 
 | ||||||
|  | 	// --
 | ||||||
|  | 
 | ||||||
|  | 	res, body = Request(t, port, "GET", "/blocks/1", nil) | ||||||
|  | 	require.Equal(t, http.StatusOK, res.StatusCode, body) | ||||||
|  | 
 | ||||||
|  | 	err = wire.Cdc.UnmarshalJSON([]byte(body), &resultBlock) | ||||||
|  | 	require.Nil(t, err, "Couldn't parse block") | ||||||
|  | 
 | ||||||
|  | 	require.NotEqual(t, ctypes.ResultBlock{}, resultBlock) | ||||||
|  | 
 | ||||||
|  | 	// --
 | ||||||
|  | 
 | ||||||
|  | 	res, body = Request(t, port, "GET", "/blocks/1000000000", nil) | ||||||
|  | 	require.Equal(t, http.StatusNotFound, res.StatusCode, body) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestValidators(t *testing.T) { | ||||||
|  | 	cleanup, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{}) | ||||||
|  | 	defer cleanup() | ||||||
|  | 
 | ||||||
|  | 	var resultVals rpc.ResultValidatorsOutput | ||||||
|  | 
 | ||||||
|  | 	res, body := Request(t, port, "GET", "/validatorsets/latest", nil) | ||||||
|  | 	require.Equal(t, http.StatusOK, res.StatusCode, body) | ||||||
|  | 
 | ||||||
|  | 	err := cdc.UnmarshalJSON([]byte(body), &resultVals) | ||||||
|  | 	require.Nil(t, err, "Couldn't parse validatorset") | ||||||
|  | 
 | ||||||
|  | 	require.NotEqual(t, rpc.ResultValidatorsOutput{}, resultVals) | ||||||
|  | 
 | ||||||
|  | 	require.Contains(t, resultVals.Validators[0].Address.String(), "cosmosvaladdr") | ||||||
|  | 	require.Contains(t, resultVals.Validators[0].PubKey, "cosmosvalpub") | ||||||
|  | 
 | ||||||
|  | 	// --
 | ||||||
|  | 
 | ||||||
|  | 	res, body = Request(t, port, "GET", "/validatorsets/1", nil) | ||||||
|  | 	require.Equal(t, http.StatusOK, res.StatusCode, body) | ||||||
|  | 
 | ||||||
|  | 	err = cdc.UnmarshalJSON([]byte(body), &resultVals) | ||||||
|  | 	require.Nil(t, err, "Couldn't parse validatorset") | ||||||
|  | 
 | ||||||
|  | 	require.NotEqual(t, rpc.ResultValidatorsOutput{}, resultVals) | ||||||
|  | 
 | ||||||
|  | 	// --
 | ||||||
|  | 
 | ||||||
|  | 	res, body = Request(t, port, "GET", "/validatorsets/1000000000", nil) | ||||||
|  | 	require.Equal(t, http.StatusNotFound, res.StatusCode, body) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestCoinSend(t *testing.T) { | ||||||
|  | 	name, password := "test", "1234567890" | ||||||
|  | 	addr, seed := CreateAddr(t, "test", password, GetKeyBase(t)) | ||||||
|  | 	cleanup, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}) | ||||||
|  | 	defer cleanup() | ||||||
|  | 
 | ||||||
|  | 	bz, err := hex.DecodeString("8FA6AB57AD6870F6B5B2E57735F38F2F30E73CB6") | ||||||
|  | 	require.NoError(t, err) | ||||||
|  | 	someFakeAddr := sdk.AccAddress(bz) | ||||||
|  | 
 | ||||||
|  | 	// query empty
 | ||||||
|  | 	res, body := Request(t, port, "GET", fmt.Sprintf("/accounts/%s", someFakeAddr), nil) | ||||||
|  | 	require.Equal(t, http.StatusNoContent, res.StatusCode, body) | ||||||
|  | 
 | ||||||
|  | 	acc := getAccount(t, port, addr) | ||||||
|  | 	initialBalance := acc.GetCoins() | ||||||
|  | 
 | ||||||
|  | 	// create TX
 | ||||||
|  | 	receiveAddr, resultTx := doSend(t, port, seed, name, password, addr) | ||||||
|  | 	tests.WaitForHeight(resultTx.Height+1, port) | ||||||
|  | 
 | ||||||
|  | 	// check if tx was committed
 | ||||||
|  | 	require.Equal(t, uint32(0), resultTx.CheckTx.Code) | ||||||
|  | 	require.Equal(t, uint32(0), resultTx.DeliverTx.Code) | ||||||
|  | 
 | ||||||
|  | 	// query sender
 | ||||||
|  | 	acc = getAccount(t, port, addr) | ||||||
|  | 	coins := acc.GetCoins() | ||||||
|  | 	mycoins := coins[0] | ||||||
|  | 
 | ||||||
|  | 	require.Equal(t, "KVA", mycoins.Denom) | ||||||
|  | 	require.Equal(t, initialBalance[0].Amount.SubRaw(1), mycoins.Amount) | ||||||
|  | 
 | ||||||
|  | 	// query receiver
 | ||||||
|  | 	acc = getAccount(t, port, receiveAddr) | ||||||
|  | 	coins = acc.GetCoins() | ||||||
|  | 	mycoins = coins[0] | ||||||
|  | 
 | ||||||
|  | 	require.Equal(t, "KVA", mycoins.Denom) | ||||||
|  | 	require.Equal(t, int64(1), mycoins.Amount.Int64()) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestTxs(t *testing.T) { | ||||||
|  | 	name, password := "test", "1234567890" | ||||||
|  | 	addr, seed := CreateAddr(t, "test", password, GetKeyBase(t)) | ||||||
|  | 	cleanup, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}) | ||||||
|  | 	defer cleanup() | ||||||
|  | 
 | ||||||
|  | 	// query wrong
 | ||||||
|  | 	res, body := Request(t, port, "GET", "/txs", nil) | ||||||
|  | 	require.Equal(t, http.StatusBadRequest, res.StatusCode, body) | ||||||
|  | 
 | ||||||
|  | 	// query empty
 | ||||||
|  | 	res, body = Request(t, port, "GET", fmt.Sprintf("/txs?tag=sender_bech32='%s'", "cosmosaccaddr1jawd35d9aq4u76sr3fjalmcqc8hqygs9gtnmv3"), nil) | ||||||
|  | 	require.Equal(t, http.StatusOK, res.StatusCode, body) | ||||||
|  | 	require.Equal(t, "[]", body) | ||||||
|  | 
 | ||||||
|  | 	// create TX
 | ||||||
|  | 	receiveAddr, resultTx := doSend(t, port, seed, name, password, addr) | ||||||
|  | 
 | ||||||
|  | 	tests.WaitForHeight(resultTx.Height+1, port) | ||||||
|  | 
 | ||||||
|  | 	// check if tx is findable
 | ||||||
|  | 	res, body = Request(t, port, "GET", fmt.Sprintf("/txs/%s", resultTx.Hash), nil) | ||||||
|  | 	require.Equal(t, http.StatusOK, res.StatusCode, body) | ||||||
|  | 
 | ||||||
|  | 	var indexedTxs []tx.Info | ||||||
|  | 
 | ||||||
|  | 	// check if tx is queryable
 | ||||||
|  | 	res, body = Request(t, port, "GET", fmt.Sprintf("/txs?tag=tx.hash='%s'", resultTx.Hash), nil) | ||||||
|  | 	require.Equal(t, http.StatusOK, res.StatusCode, body) | ||||||
|  | 	require.NotEqual(t, "[]", body) | ||||||
|  | 
 | ||||||
|  | 	err := cdc.UnmarshalJSON([]byte(body), &indexedTxs) | ||||||
|  | 	require.NoError(t, err) | ||||||
|  | 	require.Equal(t, 1, len(indexedTxs)) | ||||||
|  | 
 | ||||||
|  | 	// XXX should this move into some other testfile for txs in general?
 | ||||||
|  | 	// test if created TX hash is the correct hash
 | ||||||
|  | 	require.Equal(t, resultTx.Hash, indexedTxs[0].Hash) | ||||||
|  | 
 | ||||||
|  | 	// query sender
 | ||||||
|  | 	// also tests url decoding
 | ||||||
|  | 	res, body = Request(t, port, "GET", fmt.Sprintf("/txs?tag=sender_bech32=%%27%s%%27", addr), nil) | ||||||
|  | 	require.Equal(t, http.StatusOK, res.StatusCode, body) | ||||||
|  | 
 | ||||||
|  | 	err = cdc.UnmarshalJSON([]byte(body), &indexedTxs) | ||||||
|  | 	require.NoError(t, err) | ||||||
|  | 	require.Equal(t, 1, len(indexedTxs), "%v", indexedTxs) // there are 2 txs created with doSend
 | ||||||
|  | 	require.Equal(t, resultTx.Height, indexedTxs[0].Height) | ||||||
|  | 
 | ||||||
|  | 	// query recipient
 | ||||||
|  | 	res, body = Request(t, port, "GET", fmt.Sprintf("/txs?tag=recipient_bech32='%s'", receiveAddr), nil) | ||||||
|  | 	require.Equal(t, http.StatusOK, res.StatusCode, body) | ||||||
|  | 
 | ||||||
|  | 	err = cdc.UnmarshalJSON([]byte(body), &indexedTxs) | ||||||
|  | 	require.NoError(t, err) | ||||||
|  | 	require.Equal(t, 1, len(indexedTxs)) | ||||||
|  | 	require.Equal(t, resultTx.Height, indexedTxs[0].Height) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestValidatorsQuery(t *testing.T) { | ||||||
|  | 	cleanup, pks, port := InitializeTestLCD(t, 1, []sdk.AccAddress{}) | ||||||
|  | 	defer cleanup() | ||||||
|  | 	require.Equal(t, 1, len(pks)) | ||||||
|  | 
 | ||||||
|  | 	validators := getValidators(t, port) | ||||||
|  | 	require.Equal(t, len(validators), 1) | ||||||
|  | 
 | ||||||
|  | 	// make sure all the validators were found (order unknown because sorted by owner addr)
 | ||||||
|  | 	foundVal := false | ||||||
|  | 	pkBech := sdk.MustBech32ifyValPub(pks[0]) | ||||||
|  | 	if validators[0].PubKey == pkBech { | ||||||
|  | 		foundVal = true | ||||||
|  | 	} | ||||||
|  | 	require.True(t, foundVal, "pkBech %v, owner %v", pkBech, validators[0].Owner) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestValidatorQuery(t *testing.T) { | ||||||
|  | 	cleanup, pks, port := InitializeTestLCD(t, 1, []sdk.AccAddress{}) | ||||||
|  | 	defer cleanup() | ||||||
|  | 	require.Equal(t, 1, len(pks)) | ||||||
|  | 
 | ||||||
|  | 	validator1Owner := sdk.AccAddress(pks[0].Address()) | ||||||
|  | 
 | ||||||
|  | 	validator := getValidator(t, port, validator1Owner) | ||||||
|  | 	bech32ValAddress, err := sdk.Bech32ifyValPub(pks[0]) | ||||||
|  | 	require.NoError(t, err) | ||||||
|  | 	assert.Equal(t, validator.PubKey, bech32ValAddress, "The returned validator does not hold the correct data") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestBonding(t *testing.T) { | ||||||
|  | 	name, password, denom := "test", "1234567890", "KVA" | ||||||
|  | 	addr, seed := CreateAddr(t, "test", password, GetKeyBase(t)) | ||||||
|  | 	cleanup, pks, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}) | ||||||
|  | 	defer cleanup() | ||||||
|  | 
 | ||||||
|  | 	validator1Owner := sdk.AccAddress(pks[0].Address()) | ||||||
|  | 
 | ||||||
|  | 	// create bond TX
 | ||||||
|  | 	resultTx := doDelegate(t, port, seed, name, password, addr, validator1Owner) | ||||||
|  | 	tests.WaitForHeight(resultTx.Height+1, port) | ||||||
|  | 
 | ||||||
|  | 	// check if tx was committed
 | ||||||
|  | 	require.Equal(t, uint32(0), resultTx.CheckTx.Code) | ||||||
|  | 	require.Equal(t, uint32(0), resultTx.DeliverTx.Code) | ||||||
|  | 
 | ||||||
|  | 	// query sender
 | ||||||
|  | 	acc := getAccount(t, port, addr) | ||||||
|  | 	coins := acc.GetCoins() | ||||||
|  | 
 | ||||||
|  | 	require.Equal(t, int64(40), coins.AmountOf(denom).Int64()) | ||||||
|  | 
 | ||||||
|  | 	// query validator
 | ||||||
|  | 	bond := getDelegation(t, port, addr, validator1Owner) | ||||||
|  | 	require.Equal(t, "60.0000000000", bond.Shares) | ||||||
|  | 
 | ||||||
|  | 	//////////////////////
 | ||||||
|  | 	// testing unbonding
 | ||||||
|  | 
 | ||||||
|  | 	// create unbond TX
 | ||||||
|  | 	resultTx = doBeginUnbonding(t, port, seed, name, password, addr, validator1Owner) | ||||||
|  | 	tests.WaitForHeight(resultTx.Height+1, port) | ||||||
|  | 
 | ||||||
|  | 	// query validator
 | ||||||
|  | 	bond = getDelegation(t, port, addr, validator1Owner) | ||||||
|  | 	require.Equal(t, "30.0000000000", bond.Shares) | ||||||
|  | 
 | ||||||
|  | 	// check if tx was committed
 | ||||||
|  | 	require.Equal(t, uint32(0), resultTx.CheckTx.Code) | ||||||
|  | 	require.Equal(t, uint32(0), resultTx.DeliverTx.Code) | ||||||
|  | 
 | ||||||
|  | 	// should the sender should have not received any coins as the unbonding has only just begun
 | ||||||
|  | 	// query sender
 | ||||||
|  | 	acc = getAccount(t, port, addr) | ||||||
|  | 	coins = acc.GetCoins() | ||||||
|  | 	require.Equal(t, int64(40), coins.AmountOf("KVA").Int64()) | ||||||
|  | 
 | ||||||
|  | 	// query unbonding delegation
 | ||||||
|  | 	validatorAddr := sdk.AccAddress(pks[0].Address()) | ||||||
|  | 	unbondings := getUndelegations(t, port, addr, validatorAddr) | ||||||
|  | 	assert.Len(t, unbondings, 1, "Unbondings holds all unbonding-delegations") | ||||||
|  | 	assert.Equal(t, "30", unbondings[0].Balance.Amount.String()) | ||||||
|  | 
 | ||||||
|  | 	// query summary
 | ||||||
|  | 	summary := getDelegationSummary(t, port, addr) | ||||||
|  | 
 | ||||||
|  | 	assert.Len(t, summary.Delegations, 1, "Delegation summary holds all delegations") | ||||||
|  | 	assert.Equal(t, "30.0000000000", summary.Delegations[0].Shares) | ||||||
|  | 	assert.Len(t, summary.UnbondingDelegations, 1, "Delegation summary holds all unbonding-delegations") | ||||||
|  | 	assert.Equal(t, "30", summary.UnbondingDelegations[0].Balance.Amount.String()) | ||||||
|  | 
 | ||||||
|  | 	// TODO add redelegation, need more complex capabilities such to mock context and
 | ||||||
|  | 	// TODO check summary for redelegation
 | ||||||
|  | 	// assert.Len(t, summary.Redelegations, 1, "Delegation summary holds all redelegations")
 | ||||||
|  | 
 | ||||||
|  | 	// query txs
 | ||||||
|  | 	txs := getBondingTxs(t, port, addr, "") | ||||||
|  | 	assert.Len(t, txs, 2, "All Txs found") | ||||||
|  | 
 | ||||||
|  | 	txs = getBondingTxs(t, port, addr, "bond") | ||||||
|  | 	assert.Len(t, txs, 1, "All bonding txs found") | ||||||
|  | 
 | ||||||
|  | 	txs = getBondingTxs(t, port, addr, "unbond") | ||||||
|  | 	assert.Len(t, txs, 1, "All unbonding txs found") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestUnrevoke(t *testing.T) { | ||||||
|  | 	_, password := "test", "1234567890" | ||||||
|  | 	addr, _ := CreateAddr(t, "test", password, GetKeyBase(t)) | ||||||
|  | 	cleanup, pks, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}) | ||||||
|  | 	defer cleanup() | ||||||
|  | 
 | ||||||
|  | 	// XXX: any less than this and it fails
 | ||||||
|  | 	tests.WaitForHeight(3, port) | ||||||
|  | 	pkString, _ := sdk.Bech32ifyValPub(pks[0]) | ||||||
|  | 	signingInfo := getSigningInfo(t, port, pkString) | ||||||
|  | 	tests.WaitForHeight(4, port) | ||||||
|  | 	require.Equal(t, true, signingInfo.IndexOffset > 0) | ||||||
|  | 	require.Equal(t, time.Unix(0, 0).UTC(), signingInfo.JailedUntil) | ||||||
|  | 	require.Equal(t, true, signingInfo.SignedBlocksCounter > 0) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //_____________________________________________________________________________
 | ||||||
|  | // get the account to get the sequence
 | ||||||
|  | func getAccount(t *testing.T, port string, addr sdk.AccAddress) auth.Account { | ||||||
|  | 	res, body := Request(t, port, "GET", fmt.Sprintf("/accounts/%s", addr), nil) | ||||||
|  | 	require.Equal(t, http.StatusOK, res.StatusCode, body) | ||||||
|  | 	var acc auth.Account | ||||||
|  | 	err := cdc.UnmarshalJSON([]byte(body), &acc) | ||||||
|  | 	require.Nil(t, err) | ||||||
|  | 	return acc | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func doSend(t *testing.T, port, seed, name, password string, addr sdk.AccAddress) (receiveAddr sdk.AccAddress, resultTx ctypes.ResultBroadcastTxCommit) { | ||||||
|  | 
 | ||||||
|  | 	// create receive address
 | ||||||
|  | 	kb := client.MockKeyBase() | ||||||
|  | 	receiveInfo, _, err := kb.CreateMnemonic("receive_address", cryptoKeys.English, "1234567890", cryptoKeys.SigningAlgo("secp256k1")) | ||||||
|  | 	require.Nil(t, err) | ||||||
|  | 	receiveAddr = sdk.AccAddress(receiveInfo.GetPubKey().Address()) | ||||||
|  | 
 | ||||||
|  | 	acc := getAccount(t, port, addr) | ||||||
|  | 	accnum := acc.GetAccountNumber() | ||||||
|  | 	sequence := acc.GetSequence() | ||||||
|  | 	chainID := viper.GetString(client.FlagChainID) | ||||||
|  | 	// send
 | ||||||
|  | 	coinbz, err := cdc.MarshalJSON(sdk.NewInt64Coin("KVA", 1)) | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	jsonStr := []byte(fmt.Sprintf(`{ | ||||||
|  | 		"name":"%s", | ||||||
|  | 		"password":"%s", | ||||||
|  | 		"account_number":"%d", | ||||||
|  | 		"sequence":"%d", | ||||||
|  | 		"gas": "10000", | ||||||
|  | 		"amount":[%s], | ||||||
|  | 		"chain_id":"%s" | ||||||
|  | 	}`, name, password, accnum, sequence, coinbz, chainID)) | ||||||
|  | 	res, body := Request(t, port, "POST", fmt.Sprintf("/accounts/%s/send", receiveAddr), jsonStr) | ||||||
|  | 	require.Equal(t, http.StatusOK, res.StatusCode, body) | ||||||
|  | 
 | ||||||
|  | 	err = cdc.UnmarshalJSON([]byte(body), &resultTx) | ||||||
|  | 	require.Nil(t, err) | ||||||
|  | 
 | ||||||
|  | 	return receiveAddr, resultTx | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func getSigningInfo(t *testing.T, port string, validatorPubKey string) slashing.ValidatorSigningInfo { | ||||||
|  | 	res, body := Request(t, port, "GET", fmt.Sprintf("/slashing/signing_info/%s", validatorPubKey), nil) | ||||||
|  | 	require.Equal(t, http.StatusOK, res.StatusCode, body) | ||||||
|  | 	var signingInfo slashing.ValidatorSigningInfo | ||||||
|  | 	err := cdc.UnmarshalJSON([]byte(body), &signingInfo) | ||||||
|  | 	require.Nil(t, err) | ||||||
|  | 	return signingInfo | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ============= Stake Module ================
 | ||||||
|  | 
 | ||||||
|  | func getDelegation(t *testing.T, port string, delegatorAddr, validatorAddr sdk.AccAddress) rest.DelegationWithoutRat { | ||||||
|  | 
 | ||||||
|  | 	// get the account to get the sequence
 | ||||||
|  | 	res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/delegations/%s", delegatorAddr, validatorAddr), nil) | ||||||
|  | 	require.Equal(t, http.StatusOK, res.StatusCode, body) | ||||||
|  | 	var bond rest.DelegationWithoutRat | ||||||
|  | 	err := cdc.UnmarshalJSON([]byte(body), &bond) | ||||||
|  | 	require.Nil(t, err) | ||||||
|  | 	return bond | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func getUndelegations(t *testing.T, port string, delegatorAddr, validatorAddr sdk.AccAddress) []stake.UnbondingDelegation { | ||||||
|  | 
 | ||||||
|  | 	// get the account to get the sequence
 | ||||||
|  | 	res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/unbonding_delegations/%s", delegatorAddr, validatorAddr), nil) | ||||||
|  | 	require.Equal(t, http.StatusOK, res.StatusCode, body) | ||||||
|  | 	var unbondings []stake.UnbondingDelegation | ||||||
|  | 	err := cdc.UnmarshalJSON([]byte(body), &unbondings) | ||||||
|  | 	require.Nil(t, err) | ||||||
|  | 	return unbondings | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func getDelegationSummary(t *testing.T, port string, delegatorAddr sdk.AccAddress) rest.DelegationSummary { | ||||||
|  | 
 | ||||||
|  | 	// get the account to get the sequence
 | ||||||
|  | 	res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s", delegatorAddr), nil) | ||||||
|  | 	require.Equal(t, http.StatusOK, res.StatusCode, body) | ||||||
|  | 	var summary rest.DelegationSummary | ||||||
|  | 	err := cdc.UnmarshalJSON([]byte(body), &summary) | ||||||
|  | 	require.Nil(t, err) | ||||||
|  | 	return summary | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func getBondingTxs(t *testing.T, port string, delegatorAddr sdk.AccAddress, query string) []tx.Info { | ||||||
|  | 
 | ||||||
|  | 	// get the account to get the sequence
 | ||||||
|  | 	var res *http.Response | ||||||
|  | 	var body string | ||||||
|  | 	if len(query) > 0 { | ||||||
|  | 		res, body = Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/txs?type=%s", delegatorAddr, query), nil) | ||||||
|  | 	} else { | ||||||
|  | 		res, body = Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/txs", delegatorAddr), nil) | ||||||
|  | 	} | ||||||
|  | 	require.Equal(t, http.StatusOK, res.StatusCode, body) | ||||||
|  | 	var txs []tx.Info | ||||||
|  | 	err := cdc.UnmarshalJSON([]byte(body), &txs) | ||||||
|  | 	require.Nil(t, err) | ||||||
|  | 	return txs | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func doDelegate(t *testing.T, port, seed, name, password string, delegatorAddr, validatorAddr sdk.AccAddress) (resultTx ctypes.ResultBroadcastTxCommit) { | ||||||
|  | 	// get the account to get the sequence
 | ||||||
|  | 	acc := getAccount(t, port, delegatorAddr) | ||||||
|  | 	accnum := acc.GetAccountNumber() | ||||||
|  | 	sequence := acc.GetSequence() | ||||||
|  | 
 | ||||||
|  | 	chainID := viper.GetString(client.FlagChainID) | ||||||
|  | 
 | ||||||
|  | 	// send
 | ||||||
|  | 	jsonStr := []byte(fmt.Sprintf(`{ | ||||||
|  | 		"name": "%s", | ||||||
|  | 		"password": "%s", | ||||||
|  | 		"account_number": "%d", | ||||||
|  | 		"sequence": "%d", | ||||||
|  | 		"gas": "10000", | ||||||
|  | 		"chain_id": "%s", | ||||||
|  | 		"delegations": [ | ||||||
|  | 			{ | ||||||
|  | 				"delegator_addr": "%s", | ||||||
|  | 				"validator_addr": "%s", | ||||||
|  | 				"delegation": { "denom": "%s", "amount": "60" } | ||||||
|  | 			} | ||||||
|  | 		], | ||||||
|  | 		"begin_unbondings": [], | ||||||
|  | 		"complete_unbondings": [], | ||||||
|  | 		"begin_redelegates": [], | ||||||
|  | 		"complete_redelegates": [] | ||||||
|  | 	}`, name, password, accnum, sequence, chainID, delegatorAddr, validatorAddr, "KVA")) | ||||||
|  | 	res, body := Request(t, port, "POST", fmt.Sprintf("/stake/delegators/%s/delegations", delegatorAddr), jsonStr) | ||||||
|  | 	require.Equal(t, http.StatusOK, res.StatusCode, body) | ||||||
|  | 
 | ||||||
|  | 	var results []ctypes.ResultBroadcastTxCommit | ||||||
|  | 	err := cdc.UnmarshalJSON([]byte(body), &results) | ||||||
|  | 	require.Nil(t, err) | ||||||
|  | 
 | ||||||
|  | 	return results[0] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func doBeginUnbonding(t *testing.T, port, seed, name, password string, | ||||||
|  | 	delegatorAddr, validatorAddr sdk.AccAddress) (resultTx ctypes.ResultBroadcastTxCommit) { | ||||||
|  | 
 | ||||||
|  | 	// get the account to get the sequence
 | ||||||
|  | 	acc := getAccount(t, port, delegatorAddr) | ||||||
|  | 	accnum := acc.GetAccountNumber() | ||||||
|  | 	sequence := acc.GetSequence() | ||||||
|  | 
 | ||||||
|  | 	chainID := viper.GetString(client.FlagChainID) | ||||||
|  | 
 | ||||||
|  | 	// send
 | ||||||
|  | 	jsonStr := []byte(fmt.Sprintf(`{ | ||||||
|  | 		"name": "%s", | ||||||
|  | 		"password": "%s", | ||||||
|  | 		"account_number": "%d", | ||||||
|  | 		"sequence": "%d", | ||||||
|  | 		"gas": "20000", | ||||||
|  | 		"chain_id": "%s", | ||||||
|  | 		"delegations": [], | ||||||
|  | 		"begin_unbondings": [ | ||||||
|  | 			{ | ||||||
|  | 				"delegator_addr": "%s", | ||||||
|  | 				"validator_addr": "%s", | ||||||
|  | 				"shares": "30" | ||||||
|  | 			} | ||||||
|  | 		], | ||||||
|  | 		"complete_unbondings": [], | ||||||
|  | 		"begin_redelegates": [], | ||||||
|  | 		"complete_redelegates": [] | ||||||
|  | 	}`, name, password, accnum, sequence, chainID, delegatorAddr, validatorAddr)) | ||||||
|  | 	res, body := Request(t, port, "POST", fmt.Sprintf("/stake/delegators/%s/delegations", delegatorAddr), jsonStr) | ||||||
|  | 	require.Equal(t, http.StatusOK, res.StatusCode, body) | ||||||
|  | 
 | ||||||
|  | 	var results []ctypes.ResultBroadcastTxCommit | ||||||
|  | 	err := cdc.UnmarshalJSON([]byte(body), &results) | ||||||
|  | 	require.Nil(t, err) | ||||||
|  | 
 | ||||||
|  | 	return results[0] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func doBeginRedelegation(t *testing.T, port, seed, name, password string, | ||||||
|  | 	delegatorAddr, validatorSrcAddr, validatorDstAddr sdk.AccAddress) (resultTx ctypes.ResultBroadcastTxCommit) { | ||||||
|  | 
 | ||||||
|  | 	// get the account to get the sequence
 | ||||||
|  | 	acc := getAccount(t, port, delegatorAddr) | ||||||
|  | 	accnum := acc.GetAccountNumber() | ||||||
|  | 	sequence := acc.GetSequence() | ||||||
|  | 
 | ||||||
|  | 	chainID := viper.GetString(client.FlagChainID) | ||||||
|  | 
 | ||||||
|  | 	// send
 | ||||||
|  | 	jsonStr := []byte(fmt.Sprintf(`{ | ||||||
|  | 		"name": "%s", | ||||||
|  | 		"password": "%s", | ||||||
|  | 		"account_number": "%d", | ||||||
|  | 		"sequence": "%d", | ||||||
|  | 		"gas": "10000", | ||||||
|  | 		"chain_id": "%s", | ||||||
|  | 		"delegations": [], | ||||||
|  | 		"begin_unbondings": [], | ||||||
|  | 		"complete_unbondings": [], | ||||||
|  | 		"begin_redelegates": [ | ||||||
|  | 			{ | ||||||
|  | 				"delegator_addr": "%s", | ||||||
|  | 				"validator_src_addr": "%s", | ||||||
|  | 				"validator_dst_addr": "%s", | ||||||
|  | 				"shares": "30" | ||||||
|  | 			} | ||||||
|  | 		], | ||||||
|  | 		"complete_redelegates": [] | ||||||
|  | 	}`, name, password, accnum, sequence, chainID, delegatorAddr, validatorSrcAddr, validatorDstAddr)) | ||||||
|  | 	res, body := Request(t, port, "POST", fmt.Sprintf("/stake/delegators/%s/delegations", delegatorAddr), jsonStr) | ||||||
|  | 	require.Equal(t, http.StatusOK, res.StatusCode, body) | ||||||
|  | 
 | ||||||
|  | 	var results []ctypes.ResultBroadcastTxCommit | ||||||
|  | 	err := cdc.UnmarshalJSON([]byte(body), &results) | ||||||
|  | 	require.Nil(t, err) | ||||||
|  | 
 | ||||||
|  | 	return results[0] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func getValidators(t *testing.T, port string) []stake.BechValidator { | ||||||
|  | 	// get the account to get the sequence
 | ||||||
|  | 	res, body := Request(t, port, "GET", "/stake/validators", nil) | ||||||
|  | 	require.Equal(t, http.StatusOK, res.StatusCode, body) | ||||||
|  | 	var validators []stake.BechValidator | ||||||
|  | 	err := cdc.UnmarshalJSON([]byte(body), &validators) | ||||||
|  | 	require.Nil(t, err) | ||||||
|  | 	return validators | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func getValidator(t *testing.T, port string, validatorAddr sdk.AccAddress) stake.BechValidator { | ||||||
|  | 	// get the account to get the sequence
 | ||||||
|  | 	res, body := Request(t, port, "GET", fmt.Sprintf("/stake/validators/%s", validatorAddr.String()), nil) | ||||||
|  | 	require.Equal(t, http.StatusOK, res.StatusCode, body) | ||||||
|  | 	var validator stake.BechValidator | ||||||
|  | 	err := cdc.UnmarshalJSON([]byte(body), &validator) | ||||||
|  | 	require.Nil(t, err) | ||||||
|  | 	return validator | ||||||
|  | } | ||||||
| @ -3,32 +3,27 @@ | |||||||
| 
 | 
 | ||||||
| package lcd | package lcd | ||||||
| 
 | 
 | ||||||
| /* |  | ||||||
| import ( | import ( | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"os" | 	"os" | ||||||
| 
 | 
 | ||||||
| 	"github.com/gorilla/mux" |  | ||||||
| 	"github.com/spf13/cobra" |  | ||||||
| 	"github.com/spf13/viper" |  | ||||||
| 	"github.com/tendermint/tmlibs/log" |  | ||||||
| 
 |  | ||||||
| 	tmserver "github.com/tendermint/tendermint/rpc/lib/server" |  | ||||||
| 	cmn "github.com/tendermint/tmlibs/common" |  | ||||||
| 
 |  | ||||||
| 	client "github.com/cosmos/cosmos-sdk/client" | 	client "github.com/cosmos/cosmos-sdk/client" | ||||||
| 	"github.com/cosmos/cosmos-sdk/client/context" | 	"github.com/cosmos/cosmos-sdk/client/context" | ||||||
| 	keys "github.com/cosmos/cosmos-sdk/client/keys" | 	keys "github.com/cosmos/cosmos-sdk/client/keys" | ||||||
| 	rpc "github.com/cosmos/cosmos-sdk/client/rpc" | 	rpc "github.com/cosmos/cosmos-sdk/client/rpc" | ||||||
| 	tx "github.com/cosmos/cosmos-sdk/client/tx" | 	tx "github.com/cosmos/cosmos-sdk/client/tx" | ||||||
| 	version "github.com/cosmos/cosmos-sdk/version" |  | ||||||
| 	"github.com/cosmos/cosmos-sdk/wire" | 	"github.com/cosmos/cosmos-sdk/wire" | ||||||
| 	auth "github.com/cosmos/cosmos-sdk/x/auth/client/rest" | 	auth "github.com/cosmos/cosmos-sdk/x/auth/client/rest" | ||||||
| 	bank "github.com/cosmos/cosmos-sdk/x/bank/client/rest" | 	bank "github.com/cosmos/cosmos-sdk/x/bank/client/rest" | ||||||
| 	//ibc "github.com/cosmos/cosmos-sdk/x/ibc/client/rest"
 | 	slashing "github.com/cosmos/cosmos-sdk/x/slashing/client/rest" | ||||||
| 	//stake "github.com/cosmos/cosmos-sdk/x/stake/client/rest"
 | 	stake "github.com/cosmos/cosmos-sdk/x/stake/client/rest" | ||||||
|  | 	"github.com/gorilla/mux" | ||||||
|  | 	"github.com/spf13/cobra" | ||||||
|  | 	"github.com/spf13/viper" | ||||||
|  | 	cmn "github.com/tendermint/tendermint/libs/common" | ||||||
|  | 	"github.com/tendermint/tendermint/libs/log" | ||||||
|  | 	tmserver "github.com/tendermint/tendermint/rpc/lib/server" | ||||||
| ) | ) | ||||||
| */ |  | ||||||
| 
 | 
 | ||||||
| // ServeCommand will generate a long-running rest server
 | // ServeCommand will generate a long-running rest server
 | ||||||
| // (aka Light Client Daemon) that exposes functionality similar
 | // (aka Light Client Daemon) that exposes functionality similar
 | ||||||
| @ -36,6 +31,7 @@ import ( | |||||||
| func ServeCommand(cdc *wire.Codec) *cobra.Command { | func ServeCommand(cdc *wire.Codec) *cobra.Command { | ||||||
| 	flagListenAddr := "laddr" | 	flagListenAddr := "laddr" | ||||||
| 	flagCORS := "cors" | 	flagCORS := "cors" | ||||||
|  | 	flagMaxOpenConnections := "max-open" | ||||||
| 
 | 
 | ||||||
| 	cmd := &cobra.Command{ | 	cmd := &cobra.Command{ | ||||||
| 		Use:   "rest-server", | 		Use:   "rest-server", | ||||||
| @ -43,48 +39,59 @@ func ServeCommand(cdc *wire.Codec) *cobra.Command { | |||||||
| 		RunE: func(cmd *cobra.Command, args []string) error { | 		RunE: func(cmd *cobra.Command, args []string) error { | ||||||
| 			listenAddr := viper.GetString(flagListenAddr) | 			listenAddr := viper.GetString(flagListenAddr) | ||||||
| 			handler := createHandler(cdc) | 			handler := createHandler(cdc) | ||||||
| 			logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)). | 			logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "rest-server") | ||||||
| 				With("module", "rest-server") | 			maxOpen := viper.GetInt(flagMaxOpenConnections) | ||||||
| 			listener, err := tmserver.StartHTTPServer(listenAddr, handler, logger) | 
 | ||||||
|  | 			listener, err := tmserver.StartHTTPServer( | ||||||
|  | 				listenAddr, handler, logger, | ||||||
|  | 				tmserver.Config{MaxOpenConnections: maxOpen}, | ||||||
|  | 			) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return err | 				return err | ||||||
| 			} | 			} | ||||||
|  | 
 | ||||||
| 			logger.Info("REST server started") | 			logger.Info("REST server started") | ||||||
| 
 | 
 | ||||||
| 			// Wait forever and cleanup
 | 			// wait forever and cleanup
 | ||||||
| 			cmn.TrapSignal(func() { | 			cmn.TrapSignal(func() { | ||||||
| 				err := listener.Close() | 				err := listener.Close() | ||||||
| 				logger.Error("Error closing listener", "err", err) | 				logger.Error("error closing listener", "err", err) | ||||||
| 			}) | 			}) | ||||||
|  | 
 | ||||||
| 			return nil | 			return nil | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| 	cmd.Flags().StringP(flagListenAddr, "a", "tcp://localhost:1317", "Address for server to listen on") | 
 | ||||||
| 	cmd.Flags().String(flagCORS, "", "Set to domains that can make CORS requests (* for all)") | 	cmd.Flags().String(flagListenAddr, "tcp://localhost:1317", "The address for the server to listen on") | ||||||
| 	cmd.Flags().StringP(client.FlagChainID, "c", "", "ID of chain we connect to") | 	cmd.Flags().String(flagCORS, "", "Set the domains that can make CORS requests (* for all)") | ||||||
| 	cmd.Flags().StringP(client.FlagNode, "n", "tcp://localhost:46657", "Node to connect to") | 	cmd.Flags().String(client.FlagChainID, "", "The chain ID to connect to") | ||||||
|  | 	cmd.Flags().String(client.FlagNode, "tcp://localhost:26657", "Address of the node to connect to") | ||||||
|  | 	cmd.Flags().Int(flagMaxOpenConnections, 1000, "The number of maximum open connections") | ||||||
|  | 
 | ||||||
| 	return cmd | 	return cmd | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func createHandler(cdc *wire.Codec) http.Handler { | func createHandler(cdc *wire.Codec) http.Handler { | ||||||
| 	r := mux.NewRouter() | 	r := mux.NewRouter() | ||||||
| 	r.HandleFunc("/version", version.RequestHandler).Methods("GET") |  | ||||||
| 
 | 
 | ||||||
| 	kb, err := keys.GetKeyBase() //XXX
 | 	kb, err := keys.GetKeyBase() //XXX
 | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		panic(err) | 		panic(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	ctx := context.NewCoreContextFromViper() | 	cliCtx := context.NewCLIContext().WithCodec(cdc).WithLogger(os.Stdout) | ||||||
|  | 
 | ||||||
|  | 	r.HandleFunc("/version", CLIVersionRequestHandler).Methods("GET") | ||||||
|  | 	r.HandleFunc("/node_version", NodeVersionRequestHandler(cliCtx)).Methods("GET") | ||||||
|  | 	r.HandleFunc("/decode_tx", DecodeTxRequestHandlerFn(cliCtx, cdc)).Methods("POST") | ||||||
| 
 | 
 | ||||||
| 	// TODO make more functional? aka r = keys.RegisterRoutes(r)
 |  | ||||||
| 	keys.RegisterRoutes(r) | 	keys.RegisterRoutes(r) | ||||||
| 	rpc.RegisterRoutes(ctx, r) | 	rpc.RegisterRoutes(cliCtx, r) | ||||||
| 	tx.RegisterRoutes(ctx, r, cdc) | 	tx.RegisterRoutes(cliCtx, r, cdc) | ||||||
| 	auth.RegisterRoutes(ctx, r, cdc, "acc") | 	auth.RegisterRoutes(cliCtx, r, cdc, "acc") | ||||||
| 	bank.RegisterRoutes(ctx, r, cdc, kb) | 	bank.RegisterRoutes(cliCtx, r, cdc, kb) | ||||||
| 	//ibc.RegisterRoutes(ctx, r, cdc, kb)
 | 	stake.RegisterRoutes(cliCtx, r, cdc, kb) | ||||||
| 	//stake.RegisterRoutes(ctx, r, cdc, kb)
 | 	slashing.RegisterRoutes(cliCtx, r, cdc, kb) | ||||||
| 	r.HandleFunc("/decode_tx", DecodeTxRequestHandlerFn(ctx, cdc)).Methods("POST") | 
 | ||||||
| 	return r | 	return r | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										275
									
								
								internal/lcd/test_helpers.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										275
									
								
								internal/lcd/test_helpers.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,275 @@ | |||||||
|  | // Copyright 2016 All in Bits, inc
 | ||||||
|  | // Modifications copyright 2018 Kava Labs
 | ||||||
|  | 
 | ||||||
|  | package lcd | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"bytes" | ||||||
|  | 	"encoding/json" | ||||||
|  | 	"fmt" | ||||||
|  | 	"io/ioutil" | ||||||
|  | 	"net" | ||||||
|  | 	"net/http" | ||||||
|  | 	"os" | ||||||
|  | 	"path/filepath" | ||||||
|  | 	"strings" | ||||||
|  | 	"testing" | ||||||
|  | 
 | ||||||
|  | 	"github.com/cosmos/cosmos-sdk/client" | ||||||
|  | 	keys "github.com/cosmos/cosmos-sdk/client/keys" | ||||||
|  | 	crkeys "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/wire" | ||||||
|  | 	"github.com/cosmos/cosmos-sdk/x/auth" | ||||||
|  | 	kapp "github.com/kava-labs/kava/internal/app" | ||||||
|  | 
 | ||||||
|  | 	"github.com/spf13/viper" | ||||||
|  | 	"github.com/stretchr/testify/require" | ||||||
|  | 
 | ||||||
|  | 	abci "github.com/tendermint/tendermint/abci/types" | ||||||
|  | 	tmcfg "github.com/tendermint/tendermint/config" | ||||||
|  | 	"github.com/tendermint/tendermint/crypto" | ||||||
|  | 	"github.com/tendermint/tendermint/crypto/ed25519" | ||||||
|  | 	"github.com/tendermint/tendermint/libs/cli" | ||||||
|  | 	dbm "github.com/tendermint/tendermint/libs/db" | ||||||
|  | 	"github.com/tendermint/tendermint/libs/log" | ||||||
|  | 	nm "github.com/tendermint/tendermint/node" | ||||||
|  | 	pvm "github.com/tendermint/tendermint/privval" | ||||||
|  | 	"github.com/tendermint/tendermint/proxy" | ||||||
|  | 	tmrpc "github.com/tendermint/tendermint/rpc/lib/server" | ||||||
|  | 	tmtypes "github.com/tendermint/tendermint/types" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // makePathname creates a unique pathname for each test. It will panic if it
 | ||||||
|  | // cannot get the current working directory.
 | ||||||
|  | func makePathname() string { | ||||||
|  | 	p, err := os.Getwd() | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	sep := string(filepath.Separator) | ||||||
|  | 	return strings.Replace(p, sep, "_", -1) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetConfig returns a Tendermint config for the test cases.
 | ||||||
|  | func GetConfig() *tmcfg.Config { | ||||||
|  | 	pathname := makePathname() | ||||||
|  | 	config := tmcfg.ResetTestRoot(pathname) | ||||||
|  | 
 | ||||||
|  | 	tmAddr, _, err := server.FreeTCPAddr() | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	rcpAddr, _, err := server.FreeTCPAddr() | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	grpcAddr, _, err := server.FreeTCPAddr() | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	config.P2P.ListenAddress = tmAddr | ||||||
|  | 	config.RPC.ListenAddress = rcpAddr | ||||||
|  | 	config.RPC.GRPCListenAddress = grpcAddr | ||||||
|  | 
 | ||||||
|  | 	return config | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetKeyBase returns the LCD test keybase. It also requires that a directory
 | ||||||
|  | // could be made and a keybase could be fetched.
 | ||||||
|  | //
 | ||||||
|  | // NOTE: memDB cannot be used because the request is expecting to interact with
 | ||||||
|  | // the default location.
 | ||||||
|  | func GetKeyBase(t *testing.T) crkeys.Keybase { | ||||||
|  | 	dir, err := ioutil.TempDir("", "lcd_test") | ||||||
|  | 	require.NoError(t, err) | ||||||
|  | 
 | ||||||
|  | 	viper.Set(cli.HomeFlag, dir) | ||||||
|  | 
 | ||||||
|  | 	keybase, err := keys.GetKeyBase() | ||||||
|  | 	require.NoError(t, err) | ||||||
|  | 
 | ||||||
|  | 	return keybase | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CreateAddr adds an address to the key store and returns an address and seed.
 | ||||||
|  | // It also requires that the key could be created.
 | ||||||
|  | func CreateAddr(t *testing.T, name, password string, kb crkeys.Keybase) (sdk.AccAddress, string) { | ||||||
|  | 	var ( | ||||||
|  | 		err  error | ||||||
|  | 		info crkeys.Info | ||||||
|  | 		seed string | ||||||
|  | 	) | ||||||
|  | 
 | ||||||
|  | 	info, seed, err = kb.CreateMnemonic(name, crkeys.English, password, crkeys.Secp256k1) | ||||||
|  | 	require.NoError(t, err) | ||||||
|  | 
 | ||||||
|  | 	return sdk.AccAddress(info.GetPubKey().Address()), seed | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // InitializeTestLCD starts Tendermint and the LCD in process, listening on
 | ||||||
|  | // their respective sockets where nValidators is the total number of validators
 | ||||||
|  | // and initAddrs are the accounts to initialize with some KVA tokens. It
 | ||||||
|  | // returns a cleanup function, a set of validator public keys, and a port.
 | ||||||
|  | func InitializeTestLCD(t *testing.T, nValidators int, initAddrs []sdk.AccAddress) (func(), []crypto.PubKey, string) { | ||||||
|  | 	config := GetConfig() | ||||||
|  | 	config.Consensus.TimeoutCommit = 100 | ||||||
|  | 	config.Consensus.SkipTimeoutCommit = false | ||||||
|  | 	config.TxIndex.IndexAllTags = true | ||||||
|  | 
 | ||||||
|  | 	logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)) | ||||||
|  | 	logger = log.NewFilter(logger, log.AllowError()) | ||||||
|  | 
 | ||||||
|  | 	privValidatorFile := config.PrivValidatorFile() | ||||||
|  | 	privVal := pvm.LoadOrGenFilePV(privValidatorFile) | ||||||
|  | 	privVal.Reset() | ||||||
|  | 
 | ||||||
|  | 	db := dbm.NewMemDB() | ||||||
|  | 	app := kapp.NewKavaApp(logger, db, nil) | ||||||
|  | 	cdc = kapp.CreateKavaAppCodec() | ||||||
|  | 
 | ||||||
|  | 	genesisFile := config.GenesisFile() | ||||||
|  | 	genDoc, err := tmtypes.GenesisDocFromFile(genesisFile) | ||||||
|  | 	require.NoError(t, err) | ||||||
|  | 
 | ||||||
|  | 	if nValidators < 1 { | ||||||
|  | 		panic("InitializeTestLCD must use at least one validator") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for i := 1; i < nValidators; i++ { | ||||||
|  | 		genDoc.Validators = append(genDoc.Validators, | ||||||
|  | 			tmtypes.GenesisValidator{ | ||||||
|  | 				PubKey: ed25519.GenPrivKey().PubKey(), | ||||||
|  | 				Power:  1, | ||||||
|  | 				Name:   "val", | ||||||
|  | 			}, | ||||||
|  | 		) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var validatorsPKs []crypto.PubKey | ||||||
|  | 
 | ||||||
|  | 	// NOTE: It's bad practice to reuse public key address for the owner
 | ||||||
|  | 	// address but doing in the test for simplicity.
 | ||||||
|  | 	var appGenTxs []json.RawMessage | ||||||
|  | 	for _, gdValidator := range genDoc.Validators { | ||||||
|  | 		pk := gdValidator.PubKey | ||||||
|  | 		validatorsPKs = append(validatorsPKs, pk) | ||||||
|  | 
 | ||||||
|  | 		appGenTx, _, _, err := kapp.KavaAppGenTxNF(cdc, pk, sdk.AccAddress(pk.Address()), "test_val1") | ||||||
|  | 		require.NoError(t, err) | ||||||
|  | 
 | ||||||
|  | 		appGenTxs = append(appGenTxs, appGenTx) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	genesisState, err := kapp.KavaAppGenState(cdc, appGenTxs[:]) | ||||||
|  | 	require.NoError(t, err) | ||||||
|  | 
 | ||||||
|  | 	// add some tokens to init accounts
 | ||||||
|  | 	for _, addr := range initAddrs { | ||||||
|  | 		accAuth := auth.NewBaseAccountWithAddress(addr) | ||||||
|  | 		accAuth.Coins = sdk.Coins{sdk.NewInt64Coin("KVA", 100)} | ||||||
|  | 		acc := kapp.NewGenesisAccount(&accAuth) | ||||||
|  | 		genesisState.Accounts = append(genesisState.Accounts, acc) | ||||||
|  | 		genesisState.StakeData.Pool.LooseTokens = genesisState.StakeData.Pool.LooseTokens.Add(sdk.NewRat(100)) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	appState, err := wire.MarshalJSONIndent(cdc, genesisState) | ||||||
|  | 	require.NoError(t, err) | ||||||
|  | 	genDoc.AppState = appState | ||||||
|  | 
 | ||||||
|  | 	listenAddr, port, err := server.FreeTCPAddr() | ||||||
|  | 	require.NoError(t, err) | ||||||
|  | 
 | ||||||
|  | 	// XXX: Need to set this so LCD knows the tendermint node address!
 | ||||||
|  | 	viper.Set(client.FlagNode, config.RPC.ListenAddress) | ||||||
|  | 	viper.Set(client.FlagChainID, genDoc.ChainID) | ||||||
|  | 
 | ||||||
|  | 	node, err := startTM(config, logger, genDoc, privVal, app) | ||||||
|  | 	require.NoError(t, err) | ||||||
|  | 
 | ||||||
|  | 	lcd, err := startLCD(logger, listenAddr, cdc) | ||||||
|  | 	require.NoError(t, err) | ||||||
|  | 
 | ||||||
|  | 	tests.WaitForLCDStart(port) | ||||||
|  | 	tests.WaitForHeight(1, port) | ||||||
|  | 
 | ||||||
|  | 	cleanup := func() { | ||||||
|  | 		logger.Debug("cleaning up LCD initialization") | ||||||
|  | 		node.Stop() | ||||||
|  | 		node.Wait() | ||||||
|  | 		lcd.Close() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return cleanup, validatorsPKs, port | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // startTM creates and starts an in-process Tendermint node with memDB and
 | ||||||
|  | // in-process ABCI application. It returns the new node or any error that
 | ||||||
|  | // occurred.
 | ||||||
|  | //
 | ||||||
|  | // TODO: Clean up the WAL dir or enable it to be not persistent!
 | ||||||
|  | func startTM( | ||||||
|  | 	tmcfg *tmcfg.Config, logger log.Logger, genDoc *tmtypes.GenesisDoc, | ||||||
|  | 	privVal tmtypes.PrivValidator, app abci.Application, | ||||||
|  | ) (*nm.Node, error) { | ||||||
|  | 	genDocProvider := func() (*tmtypes.GenesisDoc, error) { return genDoc, nil } | ||||||
|  | 	dbProvider := func(*nm.DBContext) (dbm.DB, error) { return dbm.NewMemDB(), nil } | ||||||
|  | 	node, err := nm.NewNode( | ||||||
|  | 		tmcfg, | ||||||
|  | 		privVal, | ||||||
|  | 		proxy.NewLocalClientCreator(app), | ||||||
|  | 		genDocProvider, | ||||||
|  | 		dbProvider, | ||||||
|  | 		nm.DefaultMetricsProvider(tmcfg.Instrumentation), | ||||||
|  | 		logger.With("module", "node"), | ||||||
|  | 	) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	err = node.Start() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	tests.WaitForRPC(tmcfg.RPC.ListenAddress) | ||||||
|  | 	logger.Info("Tendermint running!") | ||||||
|  | 
 | ||||||
|  | 	return node, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // startLCD starts the LCD.
 | ||||||
|  | //
 | ||||||
|  | // NOTE: This causes the thread to block.
 | ||||||
|  | func startLCD(logger log.Logger, listenAddr string, cdc *wire.Codec) (net.Listener, error) { | ||||||
|  | 	return tmrpc.StartHTTPServer(listenAddr, createHandler(cdc), logger, tmrpc.Config{}) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Request makes a test LCD test request. It returns a response object and a
 | ||||||
|  | // stringified response body.
 | ||||||
|  | func Request(t *testing.T, port, method, path string, payload []byte) (*http.Response, string) { | ||||||
|  | 	var ( | ||||||
|  | 		err error | ||||||
|  | 		res *http.Response | ||||||
|  | 	) | ||||||
|  | 	url := fmt.Sprintf("http://localhost:%v%v", port, path) | ||||||
|  | 	fmt.Println("REQUEST " + method + " " + url) | ||||||
|  | 
 | ||||||
|  | 	req, err := http.NewRequest(method, url, bytes.NewBuffer(payload)) | ||||||
|  | 	require.Nil(t, err) | ||||||
|  | 
 | ||||||
|  | 	res, err = http.DefaultClient.Do(req) | ||||||
|  | 	require.Nil(t, err) | ||||||
|  | 
 | ||||||
|  | 	output, err := ioutil.ReadAll(res.Body) | ||||||
|  | 	res.Body.Close() | ||||||
|  | 	require.Nil(t, err) | ||||||
|  | 
 | ||||||
|  | 	return res, string(output) | ||||||
|  | } | ||||||
							
								
								
									
										32
									
								
								internal/lcd/version.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								internal/lcd/version.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | |||||||
|  | // Copyright 2016 All in Bits, inc
 | ||||||
|  | // Modifications copyright 2018 Kava Labs
 | ||||||
|  | 
 | ||||||
|  | package lcd | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"net/http" | ||||||
|  | 
 | ||||||
|  | 	"github.com/cosmos/cosmos-sdk/client/context" | ||||||
|  | 	"github.com/cosmos/cosmos-sdk/version" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // cli version REST handler endpoint
 | ||||||
|  | func CLIVersionRequestHandler(w http.ResponseWriter, r *http.Request) { | ||||||
|  | 	v := version.GetVersion() | ||||||
|  | 	w.Write([]byte(v)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // connected node version REST handler endpoint
 | ||||||
|  | func NodeVersionRequestHandler(cliCtx context.CLIContext) http.HandlerFunc { | ||||||
|  | 	return func(w http.ResponseWriter, r *http.Request) { | ||||||
|  | 		version, err := cliCtx.Query("/app/version") | ||||||
|  | 		if err != nil { | ||||||
|  | 			w.WriteHeader(http.StatusInternalServerError) | ||||||
|  | 			w.Write([]byte(fmt.Sprintf("Could't query version. Error: %s", err.Error()))) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		w.Write(version) | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @ -1,11 +1,12 @@ | |||||||
|  | // Copyright 2016 All in Bits, inc
 | ||||||
|  | // Modifications copyright 2018 Kava Labs
 | ||||||
|  | 
 | ||||||
| package lcd | package lcd | ||||||
| 
 | 
 | ||||||
| /* |  | ||||||
| import ( | import ( | ||||||
| 	amino "github.com/tendermint/go-amino" | 	amino "github.com/tendermint/go-amino" | ||||||
| 	ctypes "github.com/tendermint/tendermint/rpc/core/types" | 	ctypes "github.com/tendermint/tendermint/rpc/core/types" | ||||||
| ) | ) | ||||||
| */ |  | ||||||
| 
 | 
 | ||||||
| var cdc = amino.NewCodec() | var cdc = amino.NewCodec() | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Ruaridh
						Ruaridh