diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..404f6c39f --- /dev/null +++ b/.dockerignore @@ -0,0 +1,5 @@ +Dockerfile +Vagrantfile + +build/ +coverage.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index 05c7a044f..1e70c13cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,23 @@ # Changelog +## 0.15.0 (April 29, 2018) + +FEATURES: + +* Add CacheContext +* Add auto sequencing to client +* Add FeeHandler to ante handler + +BREAKING CHANGES + +* Remove go-wire, use go-amino +* [store] Add `SubspaceIterator` and `ReverseSubspaceIterator` to `KVStore` interface +* [basecoin] NewBasecoinApp takes a `dbm.DB` and uses namespaced DBs for substores + +BUG FIXES + +* MountStoreWithDB without providing a custom store works. + ## 0.14.1 (April 9, 2018) BUG FIXES diff --git a/Dockerfile b/Dockerfile index 79b078d91..a788aa641 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,28 +1,34 @@ -FROM alpine:3.5 +# Simple usage with a mounted data directory: +# > docker build -t gaia . +# > docker run -v $HOME/.gaiad:/root/.gaiad gaia init +# > docker run -v $HOME/.gaiad:/root/.gaiad gaia start -# BCHOME is where your genesis.json, key.json and other files including state are stored. -ENV BCHOME /basecoin +FROM alpine:edge -# Create a basecoin user and group first so the IDs get set the same way, even -# as the rest of this may change over time. -RUN addgroup basecoin && \ - adduser -S -G basecoin basecoin +# Set up dependencies +ENV PACKAGES go glide make git libc-dev bash -RUN mkdir -p $BCHOME && \ - chown -R basecoin:basecoin $BCHOME -WORKDIR $BCHOME +# Set up GOPATH & PATH -# Expose the basecoin home directory as a volume since there's mutable state in there. -VOLUME $BCHOME +ENV GOPATH /root/go +ENV BASE_PATH $GOPATH/src/github.com/cosmos +ENV REPO_PATH $BASE_PATH/cosmos-sdk +ENV WORKDIR /cosmos/ +ENV PATH $GOPATH/bin:$PATH -# jq and curl used for extracting `pub_key` from private validator while -# deploying tendermint with Kubernetes. It is nice to have bash so the users -# could execute bash commands. -RUN apk add --no-cache bash curl jq +# Link expected Go repo path -COPY basecoin /usr/bin/basecoin +RUN mkdir -p $WORKDIR $GOPATH/pkg $ $GOPATH/bin $BASE_PATH -ENTRYPOINT ["basecoin"] +# Add source files -# By default you will get the basecoin with local MerkleEyes and in-proc Tendermint. -CMD ["start", "--dir=${BCHOME}"] +ADD . $REPO_PATH + +# Install minimum necessary dependencies, build Cosmos SDK, remove packages +RUN apk add --no-cache $PACKAGES && \ + cd $REPO_PATH && make get_tools && make get_vendor_deps && make all && make install && \ + apk del $PACKAGES + +# Set entrypoint + +ENTRYPOINT ["gaiad"] diff --git a/Gopkg.lock b/Gopkg.lock index 4f545a614..eb2a1c8ca 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -215,8 +215,8 @@ [[projects]] name = "github.com/spf13/pflag" packages = ["."] - revision = "e57e3eeb33f795204c1ca35f56c44f83227c6e66" - version = "v1.0.0" + revision = "583c0c0531f06d5278b7d917446061adc344b5cd" + version = "v1.0.1" [[projects]] name = "github.com/spf13/viper" @@ -274,6 +274,12 @@ ] revision = "d8387025d2b9d158cf4efb07e7ebf814bcce2057" +[[projects]] + name = "github.com/tendermint/go-amino" + packages = ["."] + revision = "42246108ff925a457fb709475070a03dfd3e2b5c" + version = "0.9.6" + [[projects]] name = "github.com/tendermint/go-crypto" packages = [ @@ -283,17 +289,13 @@ "keys/words", "keys/words/wordlist" ] - revision = "c3e19f3ea26f5c3357e0bcbb799b0761ef923755" - version = "v0.5.0" + revision = "915416979bf70efa4bcbf1c6cd5d64c5fff9fc19" + version = "v0.6.2" [[projects]] name = "github.com/tendermint/go-wire" - packages = [ - ".", - "data" - ] + packages = ["."] revision = "fa721242b042ecd4c6ed1a934ee740db4f74e45c" - source = "github.com/tendermint/go-amino" version = "v0.7.3" [[projects]] @@ -338,11 +340,10 @@ "state/txindex/null", "types", "types/priv_validator", - "version", - "wire" + "version" ] - revision = "4930b61a381b9fb9bc530eb5deb56ea6429a1c3a" - version = "v0.18.0" + revision = "d0beaba7e8a5652506a34b5fab299cc2dc274c02" + version = "v0.19.0" [[projects]] name = "github.com/tendermint/tmlibs" @@ -359,8 +360,8 @@ "pubsub", "pubsub/query" ] - revision = "2e24b64fc121dcdf1cabceab8dc2f7257675483c" - version = "v0.8.1" + revision = "737154202faf75c70437f59ba5303f2eb09f5636" + version = "0.8.2-rc1" [[projects]] branch = "master" @@ -376,7 +377,7 @@ "ripemd160", "salsa20/salsa" ] - revision = "b2aa35443fbc700ab74c586ae79b81c171851023" + revision = "d6449816ce06963d9d136eee5a56fca5b0616e7e" [[projects]] branch = "master" @@ -423,7 +424,7 @@ branch = "master" name = "google.golang.org/genproto" packages = ["googleapis/rpc/status"] - revision = "ce84044298496ef4b54b4a0a0909ba593cc60e30" + revision = "51d0944304c3cbce4afe9e5247e21100037bff78" [[projects]] name = "google.golang.org/grpc" @@ -458,6 +459,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "669e58d0c4eb48e506f1abc66119c2f21b6600d4e08e8875ac83567b5c721565" + inputs-digest = "b6b2d696a242e715ddb8b25c93b3c8f7e7cabc9292eab29dffe935eddbd35fb8" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index e66037a43..86de8ca21 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -53,29 +53,28 @@ version = "~1.2.1" [[constraint]] - version = "~0.10.2" name = "github.com/tendermint/abci" + version = "~0.10.3" [[constraint]] - version = "~0.5.0" name = "github.com/tendermint/go-crypto" + version = "~0.6.2" [[constraint]] - version = "~0.7.3" - source = "github.com/tendermint/go-amino" - name = "github.com/tendermint/go-wire" + name = "github.com/tendermint/go-amino" + version = "~0.9.6" [[constraint]] - version = "~0.7.0" name = "github.com/tendermint/iavl" + version = "~0.7.0" [[constraint]] - version = "~0.18.0" name = "github.com/tendermint/tendermint" + version = "0.19.0" [[override]] - version = "~0.8.1" name = "github.com/tendermint/tmlibs" + version = "~0.8.2-rc1" [prune] go-tests = true diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index dfbb821fe..884528876 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -1,7 +1,6 @@ package baseapp import ( - "encoding/json" "fmt" "runtime/debug" @@ -72,21 +71,20 @@ func (app *BaseApp) Name() string { } // Mount a store to the provided key in the BaseApp multistore -// Broken until #532 is implemented. func (app *BaseApp) MountStoresIAVL(keys ...*sdk.KVStoreKey) { for _, key := range keys { app.MountStore(key, sdk.StoreTypeIAVL) } } -// Mount a store to the provided key in the BaseApp multistore +// Mount a store to the provided key in the BaseApp multistore, using a specified DB func (app *BaseApp) MountStoreWithDB(key sdk.StoreKey, typ sdk.StoreType, db dbm.DB) { app.cms.MountStoreWithDB(key, typ, db) } -// Mount a store to the provided key in the BaseApp multistore +// Mount a store to the provided key in the BaseApp multistore, using the default DB func (app *BaseApp) MountStore(key sdk.StoreKey, typ sdk.StoreType) { - app.cms.MountStoreWithDB(key, typ, app.db) + app.cms.MountStoreWithDB(key, typ, nil) } // nolint - Set functions @@ -241,14 +239,6 @@ func (app *BaseApp) InitChain(req abci.RequestInitChain) (res abci.ResponseInitC app.setDeliverState(abci.Header{}) app.initChainer(app.deliverState.ctx, req) // no error - // Initialize module genesis state - genesisState := new(map[string]json.RawMessage) - err := json.Unmarshal(req.AppStateBytes, genesisState) - if err != nil { - // TODO Return something intelligent - panic(err) - } - // NOTE: we don't commit, but BeginBlock for block 1 // starts from this deliverState diff --git a/baseapp/baseapp_test.go b/baseapp/baseapp_test.go index 1658c591d..78fd50464 100644 --- a/baseapp/baseapp_test.go +++ b/baseapp/baseapp_test.go @@ -35,15 +35,12 @@ func TestMountStores(t *testing.T) { // make some cap keys capKey1 := sdk.NewKVStoreKey("key1") - db1 := dbm.NewMemDB() capKey2 := sdk.NewKVStoreKey("key2") - db2 := dbm.NewMemDB() // no stores are mounted assert.Panics(t, func() { app.LoadLatestVersion(capKey1) }) - app.MountStoreWithDB(capKey1, sdk.StoreTypeIAVL, db1) - app.MountStoreWithDB(capKey2, sdk.StoreTypeIAVL, db2) + app.MountStoresIAVL(capKey1, capKey2) // stores are mounted err := app.LoadLatestVersion(capKey1) @@ -155,11 +152,8 @@ func TestInitChainer(t *testing.T) { // NOTE/TODO: mounting multiple stores is broken // see https://github.com/cosmos/cosmos-sdk/issues/532 capKey := sdk.NewKVStoreKey("main") - db1 := dbm.NewMemDB() capKey2 := sdk.NewKVStoreKey("key2") - db2 := dbm.NewMemDB() - app.MountStoreWithDB(capKey, sdk.StoreTypeIAVL, db1) - app.MountStoreWithDB(capKey2, sdk.StoreTypeIAVL, db2) + app.MountStoresIAVL(capKey, capKey2) err := app.LoadLatestVersion(capKey) // needed to make stores non-nil assert.Nil(t, err) @@ -191,8 +185,7 @@ func TestInitChainer(t *testing.T) { // reload app app = NewBaseApp(name, logger, db) - app.MountStoreWithDB(capKey, sdk.StoreTypeIAVL, db1) - app.MountStoreWithDB(capKey2, sdk.StoreTypeIAVL, db2) + app.MountStoresIAVL(capKey, capKey2) err = app.LoadLatestVersion(capKey) // needed to make stores non-nil assert.Nil(t, err) app.SetInitChainer(initChainer) @@ -432,7 +425,7 @@ func makePubKey(secret string) crypto.PubKey { func makePrivKey(secret string) crypto.PrivKey { privKey := crypto.GenPrivKeyEd25519FromSecret([]byte(secret)) - return privKey.Wrap() + return privKey } func secret(index int) string { diff --git a/client/context/viper.go b/client/context/viper.go index 750a37c61..c3b0369d9 100644 --- a/client/context/viper.go +++ b/client/context/viper.go @@ -1,27 +1,72 @@ package context import ( + "fmt" "github.com/spf13/viper" + tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" rpcclient "github.com/tendermint/tendermint/rpc/client" + tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/core" ) +// NewCoreContextFromViper - return a new context with parameters from the command line func NewCoreContextFromViper() core.CoreContext { nodeURI := viper.GetString(client.FlagNode) var rpc rpcclient.Client if nodeURI != "" { rpc = rpcclient.NewHTTP(nodeURI, "/websocket") } + chainID := viper.GetString(client.FlagChainID) + // if chain ID is not specified manually, read default chain ID + if chainID == "" { + def, err := defaultChainID() + if err != nil { + chainID = def + } + } return core.CoreContext{ - ChainID: viper.GetString(client.FlagChainID), + ChainID: chainID, Height: viper.GetInt64(client.FlagHeight), TrustNode: viper.GetBool(client.FlagTrustNode), FromAddressName: viper.GetString(client.FlagName), NodeURI: nodeURI, Sequence: viper.GetInt64(client.FlagSequence), Client: rpc, + Decoder: nil, + AccountStore: "main", } } + +// read chain ID from genesis file, if present +func defaultChainID() (string, error) { + cfg, err := tcmd.ParseConfig() + if err != nil { + return "", err + } + doc, err := tmtypes.GenesisDocFromFile(cfg.GenesisFile()) + if err != nil { + return "", err + } + return doc.ChainID, nil +} + +// EnsureSequence - automatically set sequence number if none provided +func EnsureSequence(ctx core.CoreContext) (core.CoreContext, error) { + if viper.IsSet(client.FlagSequence) { + return ctx, nil + } + from, err := ctx.GetFromAddress() + if err != nil { + return ctx, err + } + seq, err := ctx.NextSequence(from) + if err != nil { + return ctx, err + } + fmt.Printf("Defaulting to next sequence number: %d\n", seq) + ctx = ctx.WithSequence(seq) + return ctx, nil +} diff --git a/client/core/context.go b/client/core/context.go index 3d7f400a8..fac60b553 100644 --- a/client/core/context.go +++ b/client/core/context.go @@ -2,6 +2,8 @@ package core import ( rpcclient "github.com/tendermint/tendermint/rpc/client" + + sdk "github.com/cosmos/cosmos-sdk/types" ) type CoreContext struct { @@ -12,39 +14,61 @@ type CoreContext struct { FromAddressName string Sequence int64 Client rpcclient.Client + Decoder sdk.AccountDecoder + AccountStore string } +// WithChainID - return a copy of the context with an updated chainID func (c CoreContext) WithChainID(chainID string) CoreContext { c.ChainID = chainID return c } +// WithHeight - return a copy of the context with an updated height func (c CoreContext) WithHeight(height int64) CoreContext { c.Height = height return c } +// WithTrustNode - return a copy of the context with an updated TrustNode flag func (c CoreContext) WithTrustNode(trustNode bool) CoreContext { c.TrustNode = trustNode return c } +// WithNodeURI - return a copy of the context with an updated node URI func (c CoreContext) WithNodeURI(nodeURI string) CoreContext { c.NodeURI = nodeURI + c.Client = rpcclient.NewHTTP(nodeURI, "/websocket") return c } +// WithFromAddressName - return a copy of the context with an updated from address func (c CoreContext) WithFromAddressName(fromAddressName string) CoreContext { c.FromAddressName = fromAddressName return c } +// WithSequence - return a copy of the context with an updated sequence number func (c CoreContext) WithSequence(sequence int64) CoreContext { c.Sequence = sequence return c } +// WithClient - return a copy of the context with an updated RPC client instance func (c CoreContext) WithClient(client rpcclient.Client) CoreContext { c.Client = client return c } + +// WithDecoder - return a copy of the context with an updated Decoder +func (c CoreContext) WithDecoder(decoder sdk.AccountDecoder) CoreContext { + c.Decoder = decoder + return c +} + +// WithAccountStore - return a copy of the context with an updated AccountStore +func (c CoreContext) WithAccountStore(accountStore string) CoreContext { + c.AccountStore = accountStore + return c +} diff --git a/client/core/core.go b/client/core/core.go index a5c7b340c..2a1b2736a 100644 --- a/client/core/core.go +++ b/client/core/core.go @@ -91,6 +91,9 @@ func (ctx CoreContext) SignAndBuild(name, passphrase string, msg sdk.Msg, cdc *w // build the Sign Messsage from the Standard Message chainID := ctx.ChainID + if chainID == "" { + return nil, errors.Errorf("Chain ID required but not specified") + } sequence := ctx.Sequence signMsg := sdk.StdSignMsg{ ChainID: chainID, @@ -137,6 +140,25 @@ func (ctx CoreContext) SignBuildBroadcast(name string, msg sdk.Msg, cdc *wire.Co return ctx.BroadcastTx(txBytes) } +// get the next sequence for the account address +func (c CoreContext) NextSequence(address []byte) (int64, error) { + if c.Decoder == nil { + return 0, errors.New("AccountDecoder required but not provided") + } + + res, err := c.Query(address, c.AccountStore) + if err != nil { + return 0, err + } + + account, err := c.Decoder(res) + if err != nil { + panic(err) + } + + return account.GetSequence(), nil +} + // get passphrase from std input func (ctx CoreContext) GetPassphraseFromStdin(name string) (pass string, err error) { buf := client.BufferStdin() diff --git a/client/lcd/helpers.go b/client/lcd/helpers.go index 71278fca3..64814a5fc 100644 --- a/client/lcd/helpers.go +++ b/client/lcd/helpers.go @@ -7,6 +7,7 @@ import ( "os" "path/filepath" "strings" + "time" cmn "github.com/tendermint/tmlibs/common" @@ -21,11 +22,15 @@ func waitForRPC() { laddr := GetConfig().RPC.ListenAddress fmt.Println("LADDR", laddr) client := rpcclient.NewJSONRPCClient(laddr) + ctypes.RegisterAmino(client.Codec()) result := new(ctypes.ResultStatus) for { _, err := client.Call("status", map[string]interface{}{}, result) if err == nil { return + } else { + fmt.Println("error", err) + time.Sleep(time.Millisecond) } } } diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index 48cc35a8e..0e7ce7b7b 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -25,6 +25,7 @@ import ( ctypes "github.com/tendermint/tendermint/rpc/core/types" tmrpc "github.com/tendermint/tendermint/rpc/lib/server" tmtypes "github.com/tendermint/tendermint/types" + pvm "github.com/tendermint/tendermint/types/priv_validator" "github.com/tendermint/tmlibs/cli" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" @@ -34,8 +35,6 @@ import ( bapp "github.com/cosmos/cosmos-sdk/examples/basecoin/app" btypes "github.com/cosmos/cosmos-sdk/examples/basecoin/types" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/wire" - "github.com/cosmos/cosmos-sdk/x/auth" ) var ( @@ -89,7 +88,7 @@ func TestKeys(t *testing.T) { res, body = request(t, port, "GET", "/keys", nil) require.Equal(t, http.StatusOK, res.StatusCode, body) var m [2]keys.KeyOutput - err = json.Unmarshal([]byte(body), &m) + err = cdc.UnmarshalJSON([]byte(body), &m) require.Nil(t, err) assert.Equal(t, m[0].Name, name, "Did not serve keys name correctly") @@ -102,7 +101,7 @@ func TestKeys(t *testing.T) { res, body = request(t, port, "GET", keyEndpoint, nil) require.Equal(t, http.StatusOK, res.StatusCode, body) var m2 keys.KeyOutput - err = json.Unmarshal([]byte(body), &m2) + err = cdc.UnmarshalJSON([]byte(body), &m2) require.Nil(t, err) assert.Equal(t, newName, m2.Name, "Did not serve keys name correctly") @@ -142,7 +141,7 @@ func TestNodeStatus(t *testing.T) { require.Equal(t, http.StatusOK, res.StatusCode, body) var nodeInfo p2p.NodeInfo - err := json.Unmarshal([]byte(body), &nodeInfo) + err := cdc.UnmarshalJSON([]byte(body), &nodeInfo) require.Nil(t, err, "Couldn't parse node info") assert.NotEqual(t, p2p.NodeInfo{}, nodeInfo, "res: %v", res) @@ -165,7 +164,7 @@ func TestBlock(t *testing.T) { res, body := request(t, port, "GET", "/blocks/latest", nil) require.Equal(t, http.StatusOK, res.StatusCode, body) - err := json.Unmarshal([]byte(body), &resultBlock) + err := cdc.UnmarshalJSON([]byte(body), &resultBlock) require.Nil(t, err, "Couldn't parse block") assert.NotEqual(t, ctypes.ResultBlock{}, resultBlock) @@ -193,7 +192,7 @@ func TestValidators(t *testing.T) { res, body := request(t, port, "GET", "/validatorsets/latest", nil) require.Equal(t, http.StatusOK, res.StatusCode, body) - err := json.Unmarshal([]byte(body), &resultVals) + err := cdc.UnmarshalJSON([]byte(body), &resultVals) require.Nil(t, err, "Couldn't parse validatorset") assert.NotEqual(t, ctypes.ResultValidators{}, resultVals) @@ -203,7 +202,7 @@ func TestValidators(t *testing.T) { res, body = request(t, port, "GET", "/validatorsets/1", nil) require.Equal(t, http.StatusOK, res.StatusCode, body) - err = json.Unmarshal([]byte(body), &resultVals) + err = cdc.UnmarshalJSON([]byte(body), &resultVals) require.Nil(t, err, "Couldn't parse validatorset") assert.NotEqual(t, ctypes.ResultValidators{}, resultVals) @@ -220,6 +219,9 @@ func TestCoinSend(t *testing.T) { res, body := request(t, port, "GET", "/accounts/8FA6AB57AD6870F6B5B2E57735F38F2F30E73CB6", nil) require.Equal(t, http.StatusNoContent, res.StatusCode, body) + acc := getAccount(t, sendAddr) + initialBalance := acc.GetCoins() + // create TX receiveAddr, resultTx := doSend(t, port, seed) waitForHeight(resultTx.Height + 1) @@ -229,24 +231,15 @@ func TestCoinSend(t *testing.T) { assert.Equal(t, uint32(0), resultTx.DeliverTx.Code) // query sender - res, body = request(t, port, "GET", "/accounts/"+sendAddr, nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var m auth.BaseAccount - err := json.Unmarshal([]byte(body), &m) - require.Nil(t, err) - coins := m.Coins + acc = getAccount(t, sendAddr) + coins := acc.GetCoins() mycoins := coins[0] assert.Equal(t, coinDenom, mycoins.Denom) - assert.Equal(t, coinAmount-1, mycoins.Amount) + assert.Equal(t, initialBalance[0].Amount-1, mycoins.Amount) // query receiver - res, body = request(t, port, "GET", "/accounts/"+receiveAddr, nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - err = json.Unmarshal([]byte(body), &m) - require.Nil(t, err) - coins = m.Coins + acc = getAccount(t, receiveAddr) + coins = acc.GetCoins() mycoins = coins[0] assert.Equal(t, coinDenom, mycoins.Denom) assert.Equal(t, int64(1), mycoins.Amount) @@ -254,6 +247,9 @@ func TestCoinSend(t *testing.T) { func TestIBCTransfer(t *testing.T) { + acc := getAccount(t, sendAddr) + initialBalance := acc.GetCoins() + // create TX resultTx := doIBCTransfer(t, port, seed) @@ -264,16 +260,11 @@ func TestIBCTransfer(t *testing.T) { assert.Equal(t, uint32(0), resultTx.DeliverTx.Code) // query sender - res, body := request(t, port, "GET", "/accounts/"+sendAddr, nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var m auth.BaseAccount - err := json.Unmarshal([]byte(body), &m) - require.Nil(t, err) - coins := m.Coins + acc = getAccount(t, sendAddr) + coins := acc.GetCoins() mycoins := coins[0] assert.Equal(t, coinDenom, mycoins.Denom) - assert.Equal(t, coinAmount-2, mycoins.Amount) + assert.Equal(t, initialBalance[0].Amount-1, mycoins.Amount) // TODO: query ibc egress packet state } @@ -339,16 +330,12 @@ func startTMAndLCD() (*nm.Node, net.Listener, error) { config.Consensus.SkipTimeoutCommit = false logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)) - logger = log.NewFilter(logger, log.AllowError()) + // logger = log.NewFilter(logger, log.AllowError()) privValidatorFile := config.PrivValidatorFile() - privVal := tmtypes.LoadOrGenPrivValidatorFS(privValidatorFile) - dbs := map[string]dbm.DB{ - "main": dbm.NewMemDB(), - "acc": dbm.NewMemDB(), - "ibc": dbm.NewMemDB(), - "staking": dbm.NewMemDB(), - } - app := bapp.NewBasecoinApp(logger, dbs) + privVal := pvm.LoadOrGenFilePV(privValidatorFile) + db := dbm.NewMemDB() + app := bapp.NewBasecoinApp(logger, db) + cdc = bapp.MakeCodec() // XXX genesisFile := config.GenesisFile() genDoc, err := tmtypes.GenesisDocFromFile(genesisFile) @@ -372,8 +359,6 @@ func startTMAndLCD() (*nm.Node, net.Listener, error) { } genDoc.AppStateJSON = stateBytes - cdc := wire.NewCodec() - // LCD listen address port = fmt.Sprintf("%d", 17377) // XXX listenAddr := fmt.Sprintf("tcp://localhost:%s", port) // XXX @@ -386,7 +371,7 @@ func startTMAndLCD() (*nm.Node, net.Listener, error) { if err != nil { return nil, nil, err } - lcd, err := startLCD(cdc, logger, listenAddr) + lcd, err := startLCD(logger, listenAddr) if err != nil { return nil, nil, err } @@ -425,7 +410,7 @@ func startTM(cfg *tmcfg.Config, logger log.Logger, genDoc *tmtypes.GenesisDoc, p } // start the LCD. note this blocks! -func startLCD(cdc *wire.Codec, logger log.Logger, listenAddr string) (net.Listener, error) { +func startLCD(logger log.Logger, listenAddr string) (net.Listener, error) { handler := createHandler(cdc) return tmrpc.StartHTTPServer(listenAddr, handler, logger) } @@ -447,6 +432,16 @@ func request(t *testing.T, port, method, path string, payload []byte) (*http.Res return res, string(output) } +func getAccount(t *testing.T, sendAddr string) sdk.Account { + // get the account to get the sequence + res, body := request(t, port, "GET", "/accounts/"+sendAddr, nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + var acc sdk.Account + err := cdc.UnmarshalJSON([]byte(body), &acc) + require.Nil(t, err) + return acc +} + func doSend(t *testing.T, port, seed string) (receiveAddr string, resultTx ctypes.ResultBroadcastTxCommit) { // create receive address @@ -455,20 +450,15 @@ func doSend(t *testing.T, port, seed string) (receiveAddr string, resultTx ctype require.Nil(t, err) receiveAddr = receiveInfo.PubKey.Address().String() - // get the account to get the sequence - res, body := request(t, port, "GET", "/accounts/"+sendAddr, nil) - // require.Equal(t, http.StatusOK, res.StatusCode, body) - acc := auth.BaseAccount{} - err = json.Unmarshal([]byte(body), &acc) - require.Nil(t, err) - sequence := acc.Sequence + acc := getAccount(t, sendAddr) + sequence := acc.GetSequence() // send jsonStr := []byte(fmt.Sprintf(`{ "name":"%s", "password":"%s", "sequence":%d, "amount":[{ "denom": "%s", "amount": 1 }] }`, name, password, sequence, coinDenom)) - res, body = request(t, port, "POST", "/accounts/"+receiveAddr+"/send", jsonStr) + res, body := request(t, port, "POST", "/accounts/"+receiveAddr+"/send", jsonStr) require.Equal(t, http.StatusOK, res.StatusCode, body) - err = json.Unmarshal([]byte(body), &resultTx) + err = cdc.UnmarshalJSON([]byte(body), &resultTx) require.Nil(t, err) return receiveAddr, resultTx @@ -483,19 +473,15 @@ func doIBCTransfer(t *testing.T, port, seed string) (resultTx ctypes.ResultBroad receiveAddr := receiveInfo.PubKey.Address().String() // get the account to get the sequence - res, body := request(t, port, "GET", "/accounts/"+sendAddr, nil) - // require.Equal(t, http.StatusOK, res.StatusCode, body) - acc := auth.BaseAccount{} - err = json.Unmarshal([]byte(body), &acc) - require.Nil(t, err) - sequence := acc.Sequence + acc := getAccount(t, sendAddr) + sequence := acc.GetSequence() // send jsonStr := []byte(fmt.Sprintf(`{ "name":"%s", "password":"%s", "sequence":%d, "amount":[{ "denom": "%s", "amount": 1 }] }`, name, password, sequence, coinDenom)) - res, body = request(t, port, "POST", "/ibc/testchain/"+receiveAddr+"/send", jsonStr) + res, body := request(t, port, "POST", "/ibc/testchain/"+receiveAddr+"/send", jsonStr) require.Equal(t, http.StatusOK, res.StatusCode, body) - err = json.Unmarshal([]byte(body), &resultTx) + err = cdc.UnmarshalJSON([]byte(body), &resultTx) require.Nil(t, err) return resultTx @@ -517,7 +503,7 @@ func waitForHeight(height int64) { } res.Body.Close() - err = json.Unmarshal([]byte(body), &resultBlock) + err = cdc.UnmarshalJSON([]byte(body), &resultBlock) if err != nil { fmt.Println("RES", res) fmt.Println("BODY", string(body)) @@ -537,8 +523,6 @@ func waitForStart() { for { time.Sleep(time.Second) - var resultBlock ctypes.ResultBlock - url := fmt.Sprintf("http://localhost:%v%v", port, "/blocks/latest") res, err := http.Get(url) if err != nil { @@ -557,7 +541,8 @@ func waitForStart() { } res.Body.Close() - err = json.Unmarshal([]byte(body), &resultBlock) + resultBlock := new(ctypes.ResultBlock) + err = cdc.UnmarshalJSON([]byte(body), &resultBlock) if err != nil { fmt.Println("RES", res) fmt.Println("BODY", string(body)) diff --git a/client/lcd/wire.go b/client/lcd/wire.go new file mode 100644 index 000000000..f146e102e --- /dev/null +++ b/client/lcd/wire.go @@ -0,0 +1,12 @@ +package lcd + +import ( + amino "github.com/tendermint/go-amino" + ctypes "github.com/tendermint/tendermint/rpc/core/types" +) + +var cdc = amino.NewCodec() + +func init() { + ctypes.RegisterAmino(cdc) +} diff --git a/client/rpc/block.go b/client/rpc/block.go index f42a15bc2..8df26edda 100644 --- a/client/rpc/block.go +++ b/client/rpc/block.go @@ -1,7 +1,6 @@ package rpc import ( - "encoding/json" "fmt" "net/http" "strconv" @@ -49,7 +48,7 @@ func getBlock(height *int64) ([]byte, error) { // TODO move maarshalling into cmd/rest functions // output, err := tmwire.MarshalJSON(res) - output, err := json.MarshalIndent(res, "", " ") + output, err := cdc.MarshalJSON(res) if err != nil { return nil, err } @@ -65,7 +64,7 @@ func GetChainHeight() (int64, error) { if err != nil { return -1, err } - height := status.LatestBlockHeight + height := status.SyncInfo.LatestBlockHeight return height, nil } diff --git a/client/rpc/status.go b/client/rpc/status.go index 8ea8a5ad6..83fc01c56 100644 --- a/client/rpc/status.go +++ b/client/rpc/status.go @@ -1,13 +1,11 @@ package rpc import ( - "encoding/json" "fmt" "net/http" "strconv" "github.com/spf13/cobra" - wire "github.com/tendermint/go-wire" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" @@ -41,8 +39,8 @@ func printNodeStatus(cmd *cobra.Command, args []string) error { return err } - output, err := wire.MarshalJSON(status) - // output, err := json.MarshalIndent(res, " ", "") + output, err := cdc.MarshalJSON(status) + // output, err := cdc.MarshalJSONIndent(res, " ", "") if err != nil { return err } @@ -62,7 +60,7 @@ func NodeInfoRequestHandler(w http.ResponseWriter, r *http.Request) { } nodeInfo := status.NodeInfo - output, err := json.MarshalIndent(nodeInfo, "", " ") + output, err := cdc.MarshalJSON(nodeInfo) if err != nil { w.WriteHeader(500) w.Write([]byte(err.Error())) @@ -79,7 +77,7 @@ func NodeSyncingRequestHandler(w http.ResponseWriter, r *http.Request) { return } - syncing := status.Syncing + syncing := status.SyncInfo.Syncing if err != nil { w.WriteHeader(500) w.Write([]byte(err.Error())) diff --git a/client/rpc/validators.go b/client/rpc/validators.go index 9bf1505db..cdaf3be93 100644 --- a/client/rpc/validators.go +++ b/client/rpc/validators.go @@ -1,7 +1,6 @@ package rpc import ( - "encoding/json" "fmt" "net/http" "strconv" @@ -37,7 +36,7 @@ func GetValidators(height *int64) ([]byte, error) { return nil, err } - output, err := json.MarshalIndent(res, "", " ") + output, err := cdc.MarshalJSON(res) if err != nil { return nil, err } diff --git a/client/rpc/wire.go b/client/rpc/wire.go new file mode 100644 index 000000000..841366fef --- /dev/null +++ b/client/rpc/wire.go @@ -0,0 +1,12 @@ +package rpc + +import ( + amino "github.com/tendermint/go-amino" + ctypes "github.com/tendermint/tendermint/rpc/core/types" +) + +var cdc = amino.NewCodec() + +func init() { + ctypes.RegisterAmino(cdc) +} diff --git a/cmd/gaiad/main.go b/cmd/gaiad/main.go index e44bc73ea..9ebf196db 100644 --- a/cmd/gaiad/main.go +++ b/cmd/gaiad/main.go @@ -28,29 +28,11 @@ var ( // TODO: distinguish from basecoin func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { dataDir := filepath.Join(rootDir, "data") - dbMain, err := dbm.NewGoLevelDB("gaia", dataDir) + db, err := dbm.NewGoLevelDB("gaia", dataDir) if err != nil { return nil, err } - dbAcc, err := dbm.NewGoLevelDB("gaia-acc", dataDir) - if err != nil { - return nil, err - } - dbIBC, err := dbm.NewGoLevelDB("gaia-ibc", dataDir) - if err != nil { - return nil, err - } - dbStaking, err := dbm.NewGoLevelDB("gaia-staking", dataDir) - if err != nil { - return nil, err - } - dbs := map[string]dbm.DB{ - "main": dbMain, - "acc": dbAcc, - "ibc": dbIBC, - "staking": dbStaking, - } - bapp := app.NewBasecoinApp(logger, dbs) + bapp := app.NewBasecoinApp(logger, db) return bapp, nil } diff --git a/docs/apps.md b/docs/apps.md index 76434791c..29fb905cb 100644 --- a/docs/apps.md +++ b/docs/apps.md @@ -40,7 +40,7 @@ Basecoin implements a `BaseApp` state machine using the `x/auth` and `x/bank` ex which define how transaction signers are authenticated and how coins are transferred. It should also use `x/ibc` and probably a simple staking extension. -Basecoin and the native `x` extensions use go-wire for all serialization needs, +Basecoin and the native `x` extensions use go-amino for all serialization needs, including for transactions and accounts. ## Your Cosmos App @@ -62,7 +62,7 @@ Ethermint is a new implementation of `BaseApp` that does not depend on Basecoin. Instead of `cosmos-sdk/x/` it has its own `ethermint/x` based on `go-ethereum`. Ethermint uses a Patricia store for its accounts, and an IAVL store for IBC. -It has `x/ante`, which is quite similar to Basecoin's but uses RLP instead of go-wire. +It has `x/ante`, which is quite similar to Basecoin's but uses RLP instead of go-amino. Instead of `x/bank`, it has `x/eth`, which defines the single Ethereum transaction type and all the semantics of the Ethereum state machine. diff --git a/docs/guide.md b/docs/guide.md index 5c31d2e27..fe28a09cb 100644 --- a/docs/guide.md +++ b/docs/guide.md @@ -22,7 +22,7 @@ The SDK distinguishes between transactions (Tx) and messages Users can create messages containing arbitrary information by implementing the `Msg` interface: -```golang +```go type Msg interface { // Return the message type. @@ -68,7 +68,7 @@ but this is mostly for convenience and not type-safe. For instance, the `Basecoin` message types are defined in `x/bank/tx.go`: -```golang +```go type SendMsg struct { Inputs []Input `json:"inputs"` Outputs []Output `json:"outputs"` @@ -82,7 +82,7 @@ type IssueMsg struct { Each specifies the addresses that must sign the message: -```golang +```go func (msg SendMsg) GetSigners() []sdk.Address { addrs := make([]sdk.Address, len(msg.Inputs)) for i, in := range msg.Inputs { @@ -100,7 +100,7 @@ func (msg IssueMsg) GetSigners() []sdk.Address { A transaction is a message with additional information for authentication: -```golang +```go type Tx interface { GetMsg() Msg @@ -120,7 +120,7 @@ The `tx.GetSignatures()` method returns a list of signatures, which must match the list of addresses returned by `tx.Msg.GetSigners()`. The signatures come in a standard form: -```golang +```go type StdSignature struct { crypto.PubKey // optional crypto.Signature @@ -146,7 +146,7 @@ to return this. The standard way to create a transaction from a message is to use the `StdTx`: -```golang +```go type StdTx struct { Msg Signatures []StdSignature @@ -164,12 +164,12 @@ When initializing an application, a developer must specify a `TxDecoder` function which determines how an arbitrary byte array should be unmarshalled into a `Tx`: -```golang +```go type TxDecoder func(txBytes []byte) (Tx, error) ``` -In `Basecoin`, we use the Tendermint wire format and the `go-wire` library for -encoding and decoding all message types. The `go-wire` library has the nice +In `Basecoin`, we use the Tendermint wire format and the `go-amino` library for +encoding and decoding all message types. The `go-amino` library has the nice property that it can unmarshal into interface types, but it requires the relevant types to be registered ahead of type. Registration happens on a `Codec` object, so as not to taint the global name space. @@ -177,7 +177,7 @@ relevant types to be registered ahead of type. Registration happens on a For instance, in `Basecoin`, we wish to register the `SendMsg` and `IssueMsg` types: -```golang +```go cdc.RegisterInterface((*sdk.Msg)(nil), nil) cdc.RegisterConcrete(bank.SendMsg{}, "cosmos-sdk/SendMsg", nil) cdc.RegisterConcrete(bank.IssueMsg{}, "cosmos-sdk/IssueMsg", nil) @@ -186,24 +186,61 @@ cdc.RegisterConcrete(bank.IssueMsg{}, "cosmos-sdk/IssueMsg", nil) Note how each concrete type is given a name - these name determine the type's unique "prefix bytes" during encoding. A registered type will always use the same prefix-bytes, regardless of what interface it is satisfying. For more -details, see the [go-wire documentation](https://github.com/tendermint/go-wire/blob/develop). +details, see the [go-amino documentation](https://github.com/tendermint/go-amino/blob/develop). -## MultiStore +## Storage -### MultiStore is like a filesystem -### Mounting an IAVLStore +### MultiStore +MultiStore is like a root filesystem of an operating system, except +all the entries are fully Merkleized. You mount onto a MultiStore +any number of Stores. Currently only KVStores are supported, but in +the future we may support more kinds of stores, such as a HeapStore +or a NDStore for multidimensional storage. + +The MultiStore as well as all mounted stores provide caching (aka +cache-wrapping) for intermediate state (aka software transactional +memory) during the execution of transactions. In the case of the +KVStore, this also works for iterators. For example, after running +the app's AnteHandler, the MultiStore is cache-wrapped (and each +store is also cache-wrapped) so that should processing of the +transaction fail, at least the transaction fees are paid and +sequence incremented. + +The MultiStore as well as all stores support (or will support) +historical state pruning and snapshotting and various kinds of +queries with proofs. + +### KVStore + +Here we'll focus on the IAVLStore, which is a kind of KVStore. + +IAVLStore is a fast balanced dynamic Merkle store that also supports +iteration, and of course cache-wrapping, state pruning, and various +queries with proofs, such as proofs of existence, absence, range, +and so on. + +Here's how you mount them to a MultiStore. + +```go +mainDB, catDB := dbm.NewMemDB(), dbm.NewMemDB() +fooKey := sdk.NewKVStoreKey("foo") +barKey := sdk.NewKVStoreKey("bar") +catKey := sdk.NewKVStoreKey("cat") +ms := NewCommitMultiStore(mainDB) +ms.MountStoreWithDB(fooKey, sdk.StoreTypeIAVL, nil) +ms.MountStoreWithDB(barKey, sdk.StoreTypeIAVL, nil) +ms.MountStoreWithDB(catKey, sdk.StoreTypeIAVL, catDB) ``` -TODO: -- IAVLStore: Fast balanced dynamic Merkle store. - - supports iteration. -- MultiStore: multiple Merkle tree backends in a single store - - allows using Ethereum Patricia Trie and Tendermint IAVL in same app -- Provide caching for intermediate state during execution of blocks and transactions (including for iteration) -- Historical state pruning and snapshotting. -- Query proofs (existence, absence, range, etc.) on current and retained historical state. -``` + +In the example above, all IAVL nodes (inner and leaf) will be stored +in mainDB with the prefix of "s/k:foo/" and "s/k:bar/" respectively, +thus sharing the mainDB. All IAVL nodes (inner and leaf) for the +cat KVStore are stored separately in catDB with the prefix of +"s/\_/". The "s/k:KEY/" and "s/\_/" prefixes are there to +disambiguate store items from other items of non-storage concern. + ## Context @@ -223,7 +260,7 @@ Many methods on SDK objects receive a context as the first argument. Transaction processing in the SDK is defined through `Handler` functions: -```golang +```go type Handler func(ctx Context, tx Tx) Result ``` @@ -237,7 +274,7 @@ to a particular store (or two or more). Access to stores is managed using capabilities keys and mappers. When a handler is initialized, it is passed a key or mapper that gives it access to the relevant stores. -```golang +```go // File: cosmos-sdk/examples/basecoin/app/init_stores.go app.BaseApp.MountStore(app.capKeyMainStore, sdk.StoreTypeIAVL) app.accountMapper = auth.NewAccountMapper( diff --git a/docs/sdk/glossary.rst b/docs/sdk/glossary.rst index 1480e7b38..faf682da4 100644 --- a/docs/sdk/glossary.rst +++ b/docs/sdk/glossary.rst @@ -18,8 +18,7 @@ store), and it must have a deterministic action. The transaction is the main piece of one request. We currently make heavy use of -`go-wire `__ and -`data `__ to +`go-amino `__ to provide binary and json encodings and decodings for ``struct`` or interface\ ``objects. Here, encoding and decoding operations are designed to operate with interfaces nested any amount times (like an onion!). There is one public``\ TxMapper\` in the basecoin root package, and all modules can register their own @@ -162,13 +161,13 @@ also implements the ``Handler`` interface. We then register a list of modules with the dispatcher. Every module has a unique ``Name()``, which is used for isolating its state space. We use this same name for routing transactions. Each transaction implementation must be registed with -go-wire via ``TxMapper``, so we just look at the registered name of this +go-amino via ``TxMapper``, so we just look at the registered name of this transaction, which should be of the form ``/xxx``. The dispatcher grabs the appropriate module name from the tx name and routes it if the module is present. This all seems like a bit of magic, but really we're just making use of -go-wire magic that we are already using, rather than add another layer. +go-amino magic that we are already using, rather than add another layer. For all the transactions to be properly routed, the only thing you need to remember is to use the following pattern: diff --git a/docs/sdk/overview.rst b/docs/sdk/overview.rst index 9e79dd04f..1356d7dc1 100644 --- a/docs/sdk/overview.rst +++ b/docs/sdk/overview.rst @@ -278,8 +278,8 @@ into a ``Tx``: type TxDecoder func(txBytes []byte) (Tx, error) -In ``Basecoin``, we use the Tendermint wire format and the ``go-wire`` library for -encoding and decoding all message types. The ``go-wire`` library has the nice +In ``Basecoin``, we use the Tendermint wire format and the ``go-amino`` library for +encoding and decoding all message types. The ``go-amino`` library has the nice property that it can unmarshal into interface types, but it requires the relevant types to be registered ahead of type. Registration happens on a ``Codec`` object, so as not to taint the global name space. @@ -296,7 +296,7 @@ types: Note how each concrete type is given a name - these name determine the type's unique "prefix bytes" during encoding. A registered type will always use the same prefix-bytes, regardless of what interface it is satisfying. For more -details, see the `go-wire documentation `__. +details, see the `go-amino documentation `__. MultiStore diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index caae16846..ae60e8a73 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -4,7 +4,6 @@ import ( "encoding/json" abci "github.com/tendermint/abci/types" - oldwire "github.com/tendermint/go-wire" cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" @@ -37,26 +36,34 @@ type BasecoinApp struct { // Manage getting and setting accounts accountMapper sdk.AccountMapper + + // Handle fees + feeHandler sdk.FeeHandler } -func NewBasecoinApp(logger log.Logger, dbs map[string]dbm.DB) *BasecoinApp { - // create your application object +func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { + + // Create app-level codec for txs and accounts. + var cdc = MakeCodec() + + // Create your application object. var app = &BasecoinApp{ - BaseApp: bam.NewBaseApp(appName, logger, dbs["main"]), - cdc: MakeCodec(), + BaseApp: bam.NewBaseApp(appName, logger, db), + cdc: cdc, capKeyMainStore: sdk.NewKVStoreKey("main"), capKeyAccountStore: sdk.NewKVStoreKey("acc"), capKeyIBCStore: sdk.NewKVStoreKey("ibc"), capKeyStakingStore: sdk.NewKVStoreKey("stake"), } - // define the accountMapper - app.accountMapper = auth.NewAccountMapperSealed( + // Define the accountMapper. + app.accountMapper = auth.NewAccountMapper( + cdc, app.capKeyMainStore, // target store &types.AppAccount{}, // prototype - ) + ).Seal() - // add handlers + // Add handlers. coinKeeper := bank.NewCoinKeeper(app.accountMapper) ibcMapper := ibc.NewIBCMapper(app.cdc, app.capKeyIBCStore) stakeKeeper := simplestake.NewKeeper(app.capKeyStakingStore, coinKeeper) @@ -65,16 +72,14 @@ func NewBasecoinApp(logger log.Logger, dbs map[string]dbm.DB) *BasecoinApp { AddRoute("ibc", ibc.NewHandler(ibcMapper, coinKeeper)). AddRoute("simplestake", simplestake.NewHandler(stakeKeeper)) - // initialize BaseApp + // Define the feeHandler. + app.feeHandler = auth.BurnFeeHandler + + // Initialize BaseApp. app.SetTxDecoder(app.txDecoder) app.SetInitChainer(app.initChainer) - app.MountStoreWithDB(app.capKeyMainStore, sdk.StoreTypeIAVL, dbs["main"]) - app.MountStoreWithDB(app.capKeyAccountStore, sdk.StoreTypeIAVL, dbs["acc"]) - app.MountStoreWithDB(app.capKeyIBCStore, sdk.StoreTypeIAVL, dbs["ibc"]) - app.MountStoreWithDB(app.capKeyStakingStore, sdk.StoreTypeIAVL, dbs["staking"]) - // NOTE: Broken until #532 lands - //app.MountStoresIAVL(app.capKeyMainStore, app.capKeyIBCStore, app.capKeyStakingStore) - app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper)) + app.MountStoresIAVL(app.capKeyMainStore, app.capKeyAccountStore, app.capKeyIBCStore, app.capKeyStakingStore) + app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, app.feeHandler)) err := app.LoadLatestVersion(app.capKeyMainStore) if err != nil { cmn.Exit(err.Error()) @@ -83,42 +88,30 @@ func NewBasecoinApp(logger log.Logger, dbs map[string]dbm.DB) *BasecoinApp { return app } -// custom tx codec -// TODO: use new go-wire +// Custom tx codec func MakeCodec() *wire.Codec { - const msgTypeSend = 0x1 - const msgTypeIssue = 0x2 - const msgTypeQuiz = 0x3 - const msgTypeSetTrend = 0x4 - const msgTypeIBCTransferMsg = 0x5 - const msgTypeIBCReceiveMsg = 0x6 - const msgTypeBondMsg = 0x7 - const msgTypeUnbondMsg = 0x8 - var _ = oldwire.RegisterInterface( - struct{ sdk.Msg }{}, - oldwire.ConcreteType{bank.SendMsg{}, msgTypeSend}, - oldwire.ConcreteType{bank.IssueMsg{}, msgTypeIssue}, - oldwire.ConcreteType{ibc.IBCTransferMsg{}, msgTypeIBCTransferMsg}, - oldwire.ConcreteType{ibc.IBCReceiveMsg{}, msgTypeIBCReceiveMsg}, - oldwire.ConcreteType{simplestake.BondMsg{}, msgTypeBondMsg}, - oldwire.ConcreteType{simplestake.UnbondMsg{}, msgTypeUnbondMsg}, - ) + var cdc = wire.NewCodec() - const accTypeApp = 0x1 - var _ = oldwire.RegisterInterface( - struct{ sdk.Account }{}, - oldwire.ConcreteType{&types.AppAccount{}, accTypeApp}, - ) - cdc := wire.NewCodec() + // Register Msgs + cdc.RegisterInterface((*sdk.Msg)(nil), nil) + cdc.RegisterConcrete(bank.SendMsg{}, "basecoin/Send", nil) + cdc.RegisterConcrete(bank.IssueMsg{}, "basecoin/Issue", nil) + cdc.RegisterConcrete(ibc.IBCTransferMsg{}, "basecoin/IBCTransferMsg", nil) + cdc.RegisterConcrete(ibc.IBCReceiveMsg{}, "basecoin/IBCReceiveMsg", nil) + cdc.RegisterConcrete(simplestake.BondMsg{}, "basecoin/BondMsg", nil) + cdc.RegisterConcrete(simplestake.UnbondMsg{}, "basecoin/UnbondMsg", nil) + + // Register AppAccount + cdc.RegisterInterface((*sdk.Account)(nil), nil) + cdc.RegisterConcrete(&types.AppAccount{}, "basecoin/Account", nil) + + // Register crypto. + wire.RegisterCrypto(cdc) - // cdc.RegisterInterface((*sdk.Msg)(nil), nil) - // bank.RegisterWire(cdc) // Register bank.[SendMsg,IssueMsg] types. - // crypto.RegisterWire(cdc) // Register crypto.[PubKey,PrivKey,Signature] types. - // ibc.RegisterWire(cdc) // Register ibc.[IBCTransferMsg, IBCReceiveMsg] types. return cdc } -// custom logic for transaction decoding +// Custom logic for transaction decoding func (app *BasecoinApp) txDecoder(txBytes []byte) (sdk.Tx, sdk.Error) { var tx = sdk.StdTx{} @@ -127,7 +120,7 @@ func (app *BasecoinApp) txDecoder(txBytes []byte) (sdk.Tx, sdk.Error) { } // StdTx.Msg is an interface. The concrete types - // are registered by MakeTxCodec in bank.RegisterWire. + // are registered by MakeTxCodec in bank.RegisterAmino. err := app.cdc.UnmarshalBinary(txBytes, &tx) if err != nil { return nil, sdk.ErrTxDecode("").TraceCause(err, "") @@ -135,7 +128,7 @@ func (app *BasecoinApp) txDecoder(txBytes []byte) (sdk.Tx, sdk.Error) { return tx, nil } -// custom logic for basecoin initialization +// Custom logic for basecoin initialization func (app *BasecoinApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { stateJSON := req.AppStateBytes diff --git a/examples/basecoin/app/app_test.go b/examples/basecoin/app/app_test.go index 65aff3af9..ead49adc2 100644 --- a/examples/basecoin/app/app_test.go +++ b/examples/basecoin/app/app_test.go @@ -85,20 +85,15 @@ var ( } ) -func loggerAndDBs() (log.Logger, map[string]dbm.DB) { +func loggerAndDB() (log.Logger, dbm.DB) { logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app") - dbs := map[string]dbm.DB{ - "main": dbm.NewMemDB(), - "acc": dbm.NewMemDB(), - "ibc": dbm.NewMemDB(), - "staking": dbm.NewMemDB(), - } - return logger, dbs + db := dbm.NewMemDB() + return logger, db } func newBasecoinApp() *BasecoinApp { - logger, dbs := loggerAndDBs() - return NewBasecoinApp(logger, dbs) + logger, db := loggerAndDB() + return NewBasecoinApp(logger, db) } func setGenesisAccounts(bapp *BasecoinApp, accs ...auth.BaseAccount) error { @@ -142,8 +137,8 @@ func TestMsgs(t *testing.T) { } func TestSortGenesis(t *testing.T) { - logger, dbs := loggerAndDBs() - bapp := NewBasecoinApp(logger, dbs) + logger, db := loggerAndDB() + bapp := NewBasecoinApp(logger, db) // Note the order: the coins are unsorted! coinDenom1, coinDenom2 := "foocoin", "barcoin" @@ -184,8 +179,8 @@ func TestSortGenesis(t *testing.T) { } func TestGenesis(t *testing.T) { - logger, dbs := loggerAndDBs() - bapp := NewBasecoinApp(logger, dbs) + logger, db := loggerAndDB() + bapp := NewBasecoinApp(logger, db) // Construct some genesis bytes to reflect basecoin/types/AppAccount pk := crypto.GenPrivKeyEd25519().PubKey() @@ -207,7 +202,7 @@ func TestGenesis(t *testing.T) { assert.Equal(t, acc, res1) // reload app and ensure the account is still there - bapp = NewBasecoinApp(logger, dbs) + bapp = NewBasecoinApp(logger, db) ctx = bapp.BaseApp.NewContext(true, abci.Header{}) res1 = bapp.accountMapper.GetAccount(ctx, baseAcc.Address) assert.Equal(t, acc, res1) @@ -349,10 +344,9 @@ func TestQuizMsg(t *testing.T) { // Construct genesis state // Construct some genesis bytes to reflect basecoin/types/AppAccount - coins := sdk.Coins{} baseAcc := auth.BaseAccount{ Address: addr1, - Coins: coins, + Coins: nil, } acc1 := &types.AppAccount{baseAcc, "foobart"} diff --git a/examples/basecoin/cmd/basecoind/main.go b/examples/basecoin/cmd/basecoind/main.go index 34e45bf31..37eb7d58f 100644 --- a/examples/basecoin/cmd/basecoind/main.go +++ b/examples/basecoin/cmd/basecoind/main.go @@ -27,29 +27,11 @@ var ( func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { dataDir := filepath.Join(rootDir, "data") - dbMain, err := dbm.NewGoLevelDB("basecoin", dataDir) + db, err := dbm.NewGoLevelDB("basecoin", dataDir) if err != nil { return nil, err } - dbAcc, err := dbm.NewGoLevelDB("basecoin-acc", dataDir) - if err != nil { - return nil, err - } - dbIBC, err := dbm.NewGoLevelDB("basecoin-ibc", dataDir) - if err != nil { - return nil, err - } - dbStaking, err := dbm.NewGoLevelDB("basecoin-staking", dataDir) - if err != nil { - return nil, err - } - dbs := map[string]dbm.DB{ - "main": dbMain, - "acc": dbAcc, - "ibc": dbIBC, - "staking": dbStaking, - } - bapp := app.NewBasecoinApp(logger, dbs) + bapp := app.NewBasecoinApp(logger, db) return bapp, nil } diff --git a/examples/basecoin/types/account.go b/examples/basecoin/types/account.go index 35b37c7b2..e6eb5d7b4 100644 --- a/examples/basecoin/types/account.go +++ b/examples/basecoin/types/account.go @@ -12,7 +12,7 @@ var _ sdk.Account = (*AppAccount)(nil) // extending auth.BaseAccount with custom fields. // // This is compatible with the stock auth.AccountStore, since -// auth.AccountStore uses the flexible go-wire library. +// auth.AccountStore uses the flexible go-amino library. type AppAccount struct { auth.BaseAccount Name string `json:"name"` @@ -29,7 +29,7 @@ func GetAccountDecoder(cdc *wire.Codec) sdk.AccountDecoder { return nil, sdk.ErrTxDecode("accBytes are empty") } acct := new(AppAccount) - err = cdc.UnmarshalBinary(accBytes, &acct) + err = cdc.UnmarshalBinaryBare(accBytes, &acct) if err != nil { panic(err) } diff --git a/examples/democoin/app/app.go b/examples/democoin/app/app.go index 2ee79bd5b..151241d14 100644 --- a/examples/democoin/app/app.go +++ b/examples/democoin/app/app.go @@ -4,7 +4,6 @@ import ( "encoding/json" abci "github.com/tendermint/abci/types" - oldwire "github.com/tendermint/go-wire" cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" @@ -41,13 +40,20 @@ type DemocoinApp struct { // Manage getting and setting accounts accountMapper sdk.AccountMapper + + // Handle fees + feeHandler sdk.FeeHandler } -func NewDemocoinApp(logger log.Logger, dbs map[string]dbm.DB) *DemocoinApp { - // create your application object +func NewDemocoinApp(logger log.Logger, db dbm.DB) *DemocoinApp { + + // Create app-level codec for txs and accounts. + var cdc = MakeCodec() + + // Create your application object. var app = &DemocoinApp{ - BaseApp: bam.NewBaseApp(appName, logger, dbs["main"]), - cdc: MakeCodec(), + BaseApp: bam.NewBaseApp(appName, logger, db), + cdc: cdc, capKeyMainStore: sdk.NewKVStoreKey("main"), capKeyAccountStore: sdk.NewKVStoreKey("acc"), capKeyPowStore: sdk.NewKVStoreKey("pow"), @@ -55,13 +61,14 @@ func NewDemocoinApp(logger log.Logger, dbs map[string]dbm.DB) *DemocoinApp { capKeyStakingStore: sdk.NewKVStoreKey("stake"), } - // define the accountMapper - app.accountMapper = auth.NewAccountMapperSealed( + // Define the accountMapper. + app.accountMapper = auth.NewAccountMapper( + cdc, app.capKeyMainStore, // target store &types.AppAccount{}, // prototype - ) + ).Seal() - // add handlers + // Add handlers. coinKeeper := bank.NewCoinKeeper(app.accountMapper) coolKeeper := cool.NewKeeper(app.capKeyMainStore, coinKeeper) powKeeper := pow.NewKeeper(app.capKeyPowStore, pow.NewPowConfig("pow", int64(1)), coinKeeper) @@ -75,17 +82,14 @@ func NewDemocoinApp(logger log.Logger, dbs map[string]dbm.DB) *DemocoinApp { AddRoute("ibc", ibc.NewHandler(ibcMapper, coinKeeper)). AddRoute("simplestake", simplestake.NewHandler(stakeKeeper)) - // initialize BaseApp + // Define the feeHandler. + app.feeHandler = auth.BurnFeeHandler + + // Initialize BaseApp. app.SetTxDecoder(app.txDecoder) app.SetInitChainer(app.initChainerFn(coolKeeper, powKeeper)) - app.MountStoreWithDB(app.capKeyMainStore, sdk.StoreTypeIAVL, dbs["main"]) - app.MountStoreWithDB(app.capKeyAccountStore, sdk.StoreTypeIAVL, dbs["acc"]) - app.MountStoreWithDB(app.capKeyPowStore, sdk.StoreTypeIAVL, dbs["pow"]) - app.MountStoreWithDB(app.capKeyIBCStore, sdk.StoreTypeIAVL, dbs["ibc"]) - app.MountStoreWithDB(app.capKeyStakingStore, sdk.StoreTypeIAVL, dbs["staking"]) - // NOTE: Broken until #532 lands - //app.MountStoresIAVL(app.capKeyMainStore, app.capKeyIBCStore, app.capKeyStakingStore) - app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper)) + app.MountStoresIAVL(app.capKeyMainStore, app.capKeyAccountStore, app.capKeyPowStore, app.capKeyIBCStore, app.capKeyStakingStore) + app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, app.feeHandler)) err := app.LoadLatestVersion(app.capKeyMainStore) if err != nil { cmn.Exit(err.Error()) @@ -95,41 +99,28 @@ func NewDemocoinApp(logger log.Logger, dbs map[string]dbm.DB) *DemocoinApp { } // custom tx codec -// TODO: use new go-wire func MakeCodec() *wire.Codec { - const msgTypeSend = 0x1 - const msgTypeIssue = 0x2 - const msgTypeQuiz = 0x3 - const msgTypeSetTrend = 0x4 - const msgTypeMine = 0x5 - const msgTypeIBCTransferMsg = 0x6 - const msgTypeIBCReceiveMsg = 0x7 - const msgTypeBondMsg = 0x8 - const msgTypeUnbondMsg = 0x9 - var _ = oldwire.RegisterInterface( - struct{ sdk.Msg }{}, - oldwire.ConcreteType{bank.SendMsg{}, msgTypeSend}, - oldwire.ConcreteType{bank.IssueMsg{}, msgTypeIssue}, - oldwire.ConcreteType{cool.QuizMsg{}, msgTypeQuiz}, - oldwire.ConcreteType{cool.SetTrendMsg{}, msgTypeSetTrend}, - oldwire.ConcreteType{pow.MineMsg{}, msgTypeMine}, - oldwire.ConcreteType{ibc.IBCTransferMsg{}, msgTypeIBCTransferMsg}, - oldwire.ConcreteType{ibc.IBCReceiveMsg{}, msgTypeIBCReceiveMsg}, - oldwire.ConcreteType{simplestake.BondMsg{}, msgTypeBondMsg}, - oldwire.ConcreteType{simplestake.UnbondMsg{}, msgTypeUnbondMsg}, - ) + var cdc = wire.NewCodec() - const accTypeApp = 0x1 - var _ = oldwire.RegisterInterface( - struct{ sdk.Account }{}, - oldwire.ConcreteType{&types.AppAccount{}, accTypeApp}, - ) - cdc := wire.NewCodec() + // Register Msgs + cdc.RegisterInterface((*sdk.Msg)(nil), nil) + cdc.RegisterConcrete(bank.SendMsg{}, "democoin/Send", nil) + cdc.RegisterConcrete(bank.IssueMsg{}, "democoin/Issue", nil) + cdc.RegisterConcrete(cool.QuizMsg{}, "democoin/Quiz", nil) + cdc.RegisterConcrete(cool.SetTrendMsg{}, "democoin/SetTrend", nil) + cdc.RegisterConcrete(pow.MineMsg{}, "democoin/Mine", nil) + cdc.RegisterConcrete(ibc.IBCTransferMsg{}, "democoin/IBCTransferMsg", nil) + cdc.RegisterConcrete(ibc.IBCReceiveMsg{}, "democoin/IBCReceiveMsg", nil) + cdc.RegisterConcrete(simplestake.BondMsg{}, "democoin/BondMsg", nil) + cdc.RegisterConcrete(simplestake.UnbondMsg{}, "democoin/UnbondMsg", nil) + + // Register AppAccount + cdc.RegisterInterface((*sdk.Account)(nil), nil) + cdc.RegisterConcrete(&types.AppAccount{}, "democoin/Account", nil) + + // Register crypto. + wire.RegisterCrypto(cdc) - // cdc.RegisterInterface((*sdk.Msg)(nil), nil) - // bank.RegisterWire(cdc) // Register bank.[SendMsg,IssueMsg] types. - // crypto.RegisterWire(cdc) // Register crypto.[PubKey,PrivKey,Signature] types. - // ibc.RegisterWire(cdc) // Register ibc.[IBCTransferMsg, IBCReceiveMsg] types. return cdc } diff --git a/examples/democoin/app/app_test.go b/examples/democoin/app/app_test.go index 1cc56bd6b..ca4e2509e 100644 --- a/examples/democoin/app/app_test.go +++ b/examples/democoin/app/app_test.go @@ -67,21 +67,15 @@ var ( } ) -func loggerAndDBs() (log.Logger, map[string]dbm.DB) { +func loggerAndDB() (log.Logger, dbm.DB) { logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app") - dbs := map[string]dbm.DB{ - "main": dbm.NewMemDB(), - "acc": dbm.NewMemDB(), - "pow": dbm.NewMemDB(), - "ibc": dbm.NewMemDB(), - "staking": dbm.NewMemDB(), - } - return logger, dbs + db := dbm.NewMemDB() + return logger, db } func newDemocoinApp() *DemocoinApp { - logger, dbs := loggerAndDBs() - return NewDemocoinApp(logger, dbs) + logger, db := loggerAndDB() + return NewDemocoinApp(logger, db) } //_______________________________________________________________________ @@ -106,8 +100,7 @@ func TestMsgs(t *testing.T) { }}) // just marshal/unmarshal! - cdc := MakeCodec() - txBytes, err := cdc.MarshalBinary(tx) + txBytes, err := bapp.cdc.MarshalBinary(tx) require.NoError(t, err, "i: %v", i) // Run a Check @@ -124,8 +117,8 @@ func TestMsgs(t *testing.T) { } func TestGenesis(t *testing.T) { - logger, dbs := loggerAndDBs() - bapp := NewDemocoinApp(logger, dbs) + logger, db := loggerAndDB() + bapp := NewDemocoinApp(logger, db) // Construct some genesis bytes to reflect democoin/types/AppAccount pk := crypto.GenPrivKeyEd25519().PubKey() @@ -158,7 +151,7 @@ func TestGenesis(t *testing.T) { assert.Equal(t, acc, res1) // reload app and ensure the account is still there - bapp = NewDemocoinApp(logger, dbs) + bapp = NewDemocoinApp(logger, db) ctx = bapp.BaseApp.NewContext(true, abci.Header{}) res1 = bapp.accountMapper.GetAccount(ctx, baseAcc.Address) assert.Equal(t, acc, res1) @@ -245,10 +238,9 @@ func TestMineMsg(t *testing.T) { // Construct genesis state // Construct some genesis bytes to reflect democoin/types/AppAccount - coins := sdk.Coins{} baseAcc := auth.BaseAccount{ Address: addr1, - Coins: coins, + Coins: nil, } acc1 := &types.AppAccount{baseAcc, "foobart"} @@ -297,10 +289,9 @@ func TestQuizMsg(t *testing.T) { // Construct genesis state // Construct some genesis bytes to reflect democoin/types/AppAccount - coins := sdk.Coins{} baseAcc := auth.BaseAccount{ Address: addr1, - Coins: coins, + Coins: nil, } acc1 := &types.AppAccount{baseAcc, "foobart"} diff --git a/examples/democoin/cmd/democoind/main.go b/examples/democoin/cmd/democoind/main.go index df94e2c32..8f8bb5a90 100644 --- a/examples/democoin/cmd/democoind/main.go +++ b/examples/democoin/cmd/democoind/main.go @@ -47,34 +47,11 @@ func defaultAppState(args []string, addr sdk.Address, coinDenom string) (json.Ra } func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { - dbMain, err := dbm.NewGoLevelDB("democoin", filepath.Join(rootDir, "data")) + db, err := dbm.NewGoLevelDB("democoin", filepath.Join(rootDir, "data")) if err != nil { return nil, err } - dbAcc, err := dbm.NewGoLevelDB("democoin-acc", filepath.Join(rootDir, "data")) - if err != nil { - return nil, err - } - dbPow, err := dbm.NewGoLevelDB("democoin-pow", filepath.Join(rootDir, "data")) - if err != nil { - return nil, err - } - dbIBC, err := dbm.NewGoLevelDB("democoin-ibc", filepath.Join(rootDir, "data")) - if err != nil { - return nil, err - } - dbStaking, err := dbm.NewGoLevelDB("democoin-staking", filepath.Join(rootDir, "data")) - if err != nil { - return nil, err - } - dbs := map[string]dbm.DB{ - "main": dbMain, - "acc": dbAcc, - "pow": dbPow, - "ibc": dbIBC, - "staking": dbStaking, - } - bapp := app.NewDemocoinApp(logger, dbs) + bapp := app.NewDemocoinApp(logger, db) return bapp, nil } diff --git a/examples/democoin/types/account.go b/examples/democoin/types/account.go index b5d5a0d03..d90525f1d 100644 --- a/examples/democoin/types/account.go +++ b/examples/democoin/types/account.go @@ -15,7 +15,7 @@ var _ sdk.Account = (*AppAccount)(nil) // extending auth.BaseAccount with custom fields. // // This is compatible with the stock auth.AccountStore, since -// auth.AccountStore uses the flexible go-wire library. +// auth.AccountStore uses the flexible go-amino library. type AppAccount struct { auth.BaseAccount Name string `json:"name"` diff --git a/examples/democoin/x/cool/commands/tx.go b/examples/democoin/x/cool/commands/tx.go index 8deaac405..88c5e4e68 100644 --- a/examples/democoin/x/cool/commands/tx.go +++ b/examples/democoin/x/cool/commands/tx.go @@ -10,6 +10,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/wire" + authcmd "github.com/cosmos/cosmos-sdk/x/auth/commands" "github.com/cosmos/cosmos-sdk/examples/democoin/x/cool" ) @@ -24,7 +25,7 @@ func QuizTxCmd(cdc *wire.Codec) *cobra.Command { return errors.New("You must provide an answer") } - ctx := context.NewCoreContextFromViper() + ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) // get the from address from the name flag from, err := ctx.GetFromAddress() @@ -38,6 +39,12 @@ func QuizTxCmd(cdc *wire.Codec) *cobra.Command { // get account name name := viper.GetString(client.FlagName) + // default to next sequence number if none provided + ctx, err = context.EnsureSequence(ctx) + if err != nil { + return err + } + // build and sign the transaction, then broadcast to Tendermint res, err := ctx.SignBuildBroadcast(name, msg, cdc) if err != nil { @@ -60,7 +67,7 @@ func SetTrendTxCmd(cdc *wire.Codec) *cobra.Command { return errors.New("You must provide an answer") } - ctx := context.NewCoreContextFromViper() + ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) // get the from address from the name flag from, err := ctx.GetFromAddress() @@ -71,6 +78,12 @@ func SetTrendTxCmd(cdc *wire.Codec) *cobra.Command { // get account name name := viper.GetString(client.FlagName) + // default to next sequence number if none provided + ctx, err = context.EnsureSequence(ctx) + if err != nil { + return err + } + // create the message msg := cool.NewSetTrendMsg(from, args[0]) diff --git a/examples/democoin/x/pow/commands/tx.go b/examples/democoin/x/pow/commands/tx.go index badbe3909..5fa11a476 100644 --- a/examples/democoin/x/pow/commands/tx.go +++ b/examples/democoin/x/pow/commands/tx.go @@ -11,6 +11,7 @@ import ( "github.com/cosmos/cosmos-sdk/examples/democoin/x/pow" "github.com/cosmos/cosmos-sdk/wire" + authcmd "github.com/cosmos/cosmos-sdk/x/auth/commands" ) func MineCmd(cdc *wire.Codec) *cobra.Command { @@ -24,7 +25,7 @@ func MineCmd(cdc *wire.Codec) *cobra.Command { // get from address and parse arguments - ctx := context.NewCoreContextFromViper() + ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) from, err := ctx.GetFromAddress() if err != nil { @@ -53,6 +54,12 @@ func MineCmd(cdc *wire.Codec) *cobra.Command { // get account name name := ctx.FromAddressName + // default to next sequence number if none provided + ctx, err = context.EnsureSequence(ctx) + if err != nil { + return err + } + // build and sign the transaction, then broadcast to Tendermint res, err := ctx.SignBuildBroadcast(name, msg, cdc) if err != nil { diff --git a/examples/democoin/x/pow/handler_test.go b/examples/democoin/x/pow/handler_test.go index 2de285371..a05932780 100644 --- a/examples/democoin/x/pow/handler_test.go +++ b/examples/democoin/x/pow/handler_test.go @@ -8,14 +8,17 @@ import ( abci "github.com/tendermint/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" + wire "github.com/cosmos/cosmos-sdk/wire" auth "github.com/cosmos/cosmos-sdk/x/auth" bank "github.com/cosmos/cosmos-sdk/x/bank" ) func TestPowHandler(t *testing.T) { ms, capKey := setupMultiStore() + cdc := wire.NewCodec() + auth.RegisterBaseAccount(cdc) - am := auth.NewAccountMapper(capKey, &auth.BaseAccount{}) + am := auth.NewAccountMapper(cdc, capKey, &auth.BaseAccount{}) ctx := sdk.NewContext(ms, abci.Header{}, false, nil) config := NewPowConfig("pow", int64(1)) ck := bank.NewCoinKeeper(am) diff --git a/examples/democoin/x/pow/keeper_test.go b/examples/democoin/x/pow/keeper_test.go index 6e0d52649..cb3492a86 100644 --- a/examples/democoin/x/pow/keeper_test.go +++ b/examples/democoin/x/pow/keeper_test.go @@ -10,6 +10,7 @@ import ( "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" auth "github.com/cosmos/cosmos-sdk/x/auth" bank "github.com/cosmos/cosmos-sdk/x/bank" ) @@ -27,8 +28,10 @@ func setupMultiStore() (sdk.MultiStore, *sdk.KVStoreKey) { func TestPowKeeperGetSet(t *testing.T) { ms, capKey := setupMultiStore() + cdc := wire.NewCodec() + auth.RegisterBaseAccount(cdc) - am := auth.NewAccountMapper(capKey, &auth.BaseAccount{}) + am := auth.NewAccountMapper(cdc, capKey, &auth.BaseAccount{}) ctx := sdk.NewContext(ms, abci.Header{}, false, nil) config := NewPowConfig("pow", int64(1)) ck := bank.NewCoinKeeper(am) diff --git a/server/init.go b/server/init.go index 688bc38e3..8c82d2796 100644 --- a/server/init.go +++ b/server/init.go @@ -6,6 +6,7 @@ import ( "io/ioutil" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" "github.com/spf13/cobra" "github.com/tendermint/go-crypto/keys" @@ -13,6 +14,7 @@ import ( cfg "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/p2p" tmtypes "github.com/tendermint/tendermint/types" + pvm "github.com/tendermint/tendermint/types/priv_validator" cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" ) @@ -96,7 +98,7 @@ func (c initCmd) run(cmd *cobra.Command, args []string) error { return err } testnetInfo.NodeID = nodeKey.ID() - out, err := json.MarshalIndent(testnetInfo, "", " ") + out, err := wire.MarshalJSONIndent(cdc, testnetInfo) if err != nil { return err } @@ -109,12 +111,12 @@ func (c initCmd) run(cmd *cobra.Command, args []string) error { func (c initCmd) initTendermintFiles(config *cfg.Config, info *testnetInformation) error { // private validator privValFile := config.PrivValidatorFile() - var privValidator *tmtypes.PrivValidatorFS + var privValidator *pvm.FilePV if cmn.FileExists(privValFile) { - privValidator = tmtypes.LoadPrivValidatorFS(privValFile) + privValidator = pvm.LoadFilePV(privValFile) c.context.Logger.Info("Found private validator", "path", privValFile) } else { - privValidator = tmtypes.GenPrivValidatorFS(privValFile) + privValidator = pvm.GenFilePV(privValFile) privValidator.Save() c.context.Logger.Info("Generated private validator", "path", privValFile) } @@ -193,13 +195,13 @@ func addGenesisState(filename string, appState json.RawMessage) error { } var doc GenesisDoc - err = json.Unmarshal(bz, &doc) + err = cdc.UnmarshalJSON(bz, &doc) if err != nil { return err } doc["app_state"] = appState - out, err := json.MarshalIndent(doc, "", " ") + out, err := wire.MarshalJSONIndent(cdc, doc) if err != nil { return err } diff --git a/server/start.go b/server/start.go index 6aee5d316..a4ff9852e 100644 --- a/server/start.go +++ b/server/start.go @@ -11,7 +11,7 @@ import ( tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" "github.com/tendermint/tendermint/node" "github.com/tendermint/tendermint/proxy" - "github.com/tendermint/tendermint/types" + pvm "github.com/tendermint/tendermint/types/priv_validator" cmn "github.com/tendermint/tmlibs/common" "github.com/tendermint/tmlibs/log" ) @@ -95,7 +95,7 @@ func (s startCmd) startInProcess() error { // Create & start tendermint node n, err := node.NewNode(cfg, - types.LoadOrGenPrivValidatorFS(cfg.PrivValidatorFile()), + pvm.LoadOrGenFilePV(cfg.PrivValidatorFile()), proxy.NewLocalClientCreator(app), node.DefaultGenesisDocProviderFunc(cfg), node.DefaultDBProvider, diff --git a/server/tm_cmds.go b/server/tm_cmds.go index 3e0aefa94..2a9b680e5 100644 --- a/server/tm_cmds.go +++ b/server/tm_cmds.go @@ -5,10 +5,9 @@ import ( "github.com/spf13/cobra" - "github.com/tendermint/go-wire/data" tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" "github.com/tendermint/tendermint/p2p" - "github.com/tendermint/tendermint/types" + pvm "github.com/tendermint/tendermint/types/priv_validator" ) // ShowNodeIDCmd - ported from Tendermint, dump node ID to stdout @@ -53,8 +52,8 @@ type showValidator struct { func (s showValidator) run(cmd *cobra.Command, args []string) error { cfg := s.context.Config - privValidator := types.LoadOrGenPrivValidatorFS(cfg.PrivValidatorFile()) - pubKeyJSONBytes, err := data.ToJSON(privValidator.PubKey) + privValidator := pvm.LoadOrGenFilePV(cfg.PrivValidatorFile()) + pubKeyJSONBytes, err := cdc.MarshalJSON(privValidator.PubKey) if err != nil { return err } diff --git a/server/wire.go b/server/wire.go new file mode 100644 index 000000000..261e7cfe1 --- /dev/null +++ b/server/wire.go @@ -0,0 +1,12 @@ +package server + +import ( + "github.com/cosmos/cosmos-sdk/wire" +) + +var cdc *wire.Codec + +func init() { + cdc = wire.NewCodec() + wire.RegisterCrypto(cdc) +} diff --git a/store/cachekvstore.go b/store/cachekvstore.go index e075e7847..6c5cc9542 100644 --- a/store/cachekvstore.go +++ b/store/cachekvstore.go @@ -5,6 +5,7 @@ import ( "sort" "sync" + sdk "github.com/cosmos/cosmos-sdk/types" cmn "github.com/tendermint/tmlibs/common" ) @@ -134,6 +135,16 @@ func (ci *cacheKVStore) ReverseIterator(start, end []byte) Iterator { return ci.iterator(start, end, false) } +// Implements KVStore. +func (ci *cacheKVStore) SubspaceIterator(prefix []byte) Iterator { + return ci.iterator(prefix, sdk.PrefixEndBytes(prefix), true) +} + +// Implements KVStore. +func (ci *cacheKVStore) ReverseSubspaceIterator(prefix []byte) Iterator { + return ci.iterator(prefix, sdk.PrefixEndBytes(prefix), false) +} + func (ci *cacheKVStore) iterator(start, end []byte, ascending bool) Iterator { var parent, cache Iterator if ascending { diff --git a/store/dbstoreadapter.go b/store/dbstoreadapter.go index a1b580fd4..10c175a99 100644 --- a/store/dbstoreadapter.go +++ b/store/dbstoreadapter.go @@ -19,5 +19,13 @@ func (dsa dbStoreAdapter) CacheWrap() CacheWrap { return NewCacheKVStore(dsa) } +func (dsa dbStoreAdapter) SubspaceIterator(prefix []byte) Iterator { + return dsa.Iterator(prefix, sdk.PrefixEndBytes(prefix)) +} + +func (dsa dbStoreAdapter) ReverseSubspaceIterator(prefix []byte) Iterator { + return dsa.ReverseIterator(prefix, sdk.PrefixEndBytes(prefix)) +} + // dbm.DB implements KVStore so we can CacheKVStore it. var _ KVStore = dbStoreAdapter{dbm.DB(nil)} diff --git a/store/iavlstore.go b/store/iavlstore.go index e736fbda2..7d006d3c1 100644 --- a/store/iavlstore.go +++ b/store/iavlstore.go @@ -119,18 +119,21 @@ func (st *iavlStore) Iterator(start, end []byte) Iterator { return newIAVLIterator(st.tree.Tree(), start, end, true) } -func (st *iavlStore) Subspace(prefix []byte) Iterator { - end := make([]byte, len(prefix)) - copy(end, prefix) - end[len(end)-1]++ - return st.Iterator(prefix, end) -} - -// Implements IterKVStore. +// Implements KVStore. func (st *iavlStore) ReverseIterator(start, end []byte) Iterator { return newIAVLIterator(st.tree.Tree(), start, end, false) } +// Implements KVStore. +func (st *iavlStore) SubspaceIterator(prefix []byte) Iterator { + return st.Iterator(prefix, sdk.PrefixEndBytes(prefix)) +} + +// Implements KVStore. +func (st *iavlStore) ReverseSubspaceIterator(prefix []byte) Iterator { + return st.ReverseIterator(prefix, sdk.PrefixEndBytes(prefix)) +} + // Query implements ABCI interface, allows queries // // by default we will return from (latest height -1), @@ -339,6 +342,9 @@ func (iter *iavlIterator) assertIsValid() { //---------------------------------------- func cp(bz []byte) (ret []byte) { + if bz == nil { + return nil + } ret = make([]byte, len(bz)) copy(ret, bz) return ret diff --git a/store/iavlstore_test.go b/store/iavlstore_test.go index 7adae625e..824617c26 100644 --- a/store/iavlstore_test.go +++ b/store/iavlstore_test.go @@ -73,16 +73,74 @@ func TestIAVLIterator(t *testing.T) { iavlStore := newIAVLStore(tree, numHistory) iter := iavlStore.Iterator([]byte("aloha"), []byte("hellz")) expected := []string{"aloha", "hello"} - for i := 0; iter.Valid(); iter.Next() { + var i int + + for i = 0; iter.Valid(); iter.Next() { expectedKey := expected[i] key, value := iter.Key(), iter.Value() assert.EqualValues(t, key, expectedKey) assert.EqualValues(t, value, treeData[expectedKey]) i += 1 } + assert.Equal(t, len(expected), i) + + iter = iavlStore.Iterator([]byte("golang"), []byte("rocks")) + expected = []string{"hello"} + for i = 0; iter.Valid(); iter.Next() { + expectedKey := expected[i] + key, value := iter.Key(), iter.Value() + assert.EqualValues(t, key, expectedKey) + assert.EqualValues(t, value, treeData[expectedKey]) + i += 1 + } + assert.Equal(t, len(expected), i) + + iter = iavlStore.Iterator(nil, []byte("golang")) + expected = []string{"aloha"} + for i = 0; iter.Valid(); iter.Next() { + expectedKey := expected[i] + key, value := iter.Key(), iter.Value() + assert.EqualValues(t, key, expectedKey) + assert.EqualValues(t, value, treeData[expectedKey]) + i += 1 + } + assert.Equal(t, len(expected), i) + + iter = iavlStore.Iterator(nil, []byte("shalom")) + expected = []string{"aloha", "hello"} + for i = 0; iter.Valid(); iter.Next() { + expectedKey := expected[i] + key, value := iter.Key(), iter.Value() + assert.EqualValues(t, key, expectedKey) + assert.EqualValues(t, value, treeData[expectedKey]) + i += 1 + } + assert.Equal(t, len(expected), i) + + iter = iavlStore.Iterator(nil, nil) + expected = []string{"aloha", "hello"} + for i = 0; iter.Valid(); iter.Next() { + expectedKey := expected[i] + key, value := iter.Key(), iter.Value() + assert.EqualValues(t, key, expectedKey) + assert.EqualValues(t, value, treeData[expectedKey]) + i += 1 + } + assert.Equal(t, len(expected), i) + + iter = iavlStore.Iterator([]byte("golang"), nil) + expected = []string{"hello"} + for i = 0; iter.Valid(); iter.Next() { + expectedKey := expected[i] + key, value := iter.Key(), iter.Value() + assert.EqualValues(t, key, expectedKey) + assert.EqualValues(t, value, treeData[expectedKey]) + i += 1 + } + assert.Equal(t, len(expected), i) } -func TestIAVLSubspace(t *testing.T) { +func TestIAVLSubspaceIterator(t *testing.T) { db := dbm.NewMemDB() tree, _ := newTree(t, db) iavlStore := newIAVLStore(tree, numHistory) @@ -90,16 +148,114 @@ func TestIAVLSubspace(t *testing.T) { iavlStore.Set([]byte("test1"), []byte("test1")) iavlStore.Set([]byte("test2"), []byte("test2")) iavlStore.Set([]byte("test3"), []byte("test3")) + iavlStore.Set([]byte{byte(55), byte(255), byte(255), byte(0)}, []byte("test4")) + iavlStore.Set([]byte{byte(55), byte(255), byte(255), byte(1)}, []byte("test4")) + iavlStore.Set([]byte{byte(55), byte(255), byte(255), byte(255)}, []byte("test4")) + iavlStore.Set([]byte{byte(255), byte(255), byte(0)}, []byte("test4")) + iavlStore.Set([]byte{byte(255), byte(255), byte(1)}, []byte("test4")) + iavlStore.Set([]byte{byte(255), byte(255), byte(255)}, []byte("test4")) - iter := iavlStore.Subspace([]byte("test")) + i := 0 + + iter := iavlStore.SubspaceIterator([]byte("test")) expected := []string{"test1", "test2", "test3"} - for i := 0; iter.Valid(); iter.Next() { + for i = 0; iter.Valid(); iter.Next() { expectedKey := expected[i] key, value := iter.Key(), iter.Value() assert.EqualValues(t, key, expectedKey) assert.EqualValues(t, value, expectedKey) i += 1 } + assert.Equal(t, len(expected), i) + + iter = iavlStore.SubspaceIterator([]byte{byte(55), byte(255), byte(255)}) + expected2 := [][]byte{ + []byte{byte(55), byte(255), byte(255), byte(0)}, + []byte{byte(55), byte(255), byte(255), byte(1)}, + []byte{byte(55), byte(255), byte(255), byte(255)}, + } + for i = 0; iter.Valid(); iter.Next() { + expectedKey := expected2[i] + key, value := iter.Key(), iter.Value() + assert.EqualValues(t, key, expectedKey) + assert.EqualValues(t, value, []byte("test4")) + i += 1 + } + assert.Equal(t, len(expected), i) + + iter = iavlStore.SubspaceIterator([]byte{byte(255), byte(255)}) + expected2 = [][]byte{ + []byte{byte(255), byte(255), byte(0)}, + []byte{byte(255), byte(255), byte(1)}, + []byte{byte(255), byte(255), byte(255)}, + } + for i = 0; iter.Valid(); iter.Next() { + expectedKey := expected2[i] + key, value := iter.Key(), iter.Value() + assert.EqualValues(t, key, expectedKey) + assert.EqualValues(t, value, []byte("test4")) + i += 1 + } + assert.Equal(t, len(expected), i) +} + +func TestIAVLReverseSubspaceIterator(t *testing.T) { + db := dbm.NewMemDB() + tree, _ := newTree(t, db) + iavlStore := newIAVLStore(tree, numHistory) + + iavlStore.Set([]byte("test1"), []byte("test1")) + iavlStore.Set([]byte("test2"), []byte("test2")) + iavlStore.Set([]byte("test3"), []byte("test3")) + iavlStore.Set([]byte{byte(55), byte(255), byte(255), byte(0)}, []byte("test4")) + iavlStore.Set([]byte{byte(55), byte(255), byte(255), byte(1)}, []byte("test4")) + iavlStore.Set([]byte{byte(55), byte(255), byte(255), byte(255)}, []byte("test4")) + iavlStore.Set([]byte{byte(255), byte(255), byte(0)}, []byte("test4")) + iavlStore.Set([]byte{byte(255), byte(255), byte(1)}, []byte("test4")) + iavlStore.Set([]byte{byte(255), byte(255), byte(255)}, []byte("test4")) + + i := 0 + + iter := iavlStore.ReverseSubspaceIterator([]byte("test")) + expected := []string{"test3", "test2", "test1"} + for i = 0; iter.Valid(); iter.Next() { + expectedKey := expected[i] + key, value := iter.Key(), iter.Value() + assert.EqualValues(t, key, expectedKey) + assert.EqualValues(t, value, expectedKey) + i += 1 + } + assert.Equal(t, len(expected), i) + + iter = iavlStore.ReverseSubspaceIterator([]byte{byte(55), byte(255), byte(255)}) + expected2 := [][]byte{ + []byte{byte(55), byte(255), byte(255), byte(255)}, + []byte{byte(55), byte(255), byte(255), byte(1)}, + []byte{byte(55), byte(255), byte(255), byte(0)}, + } + for i = 0; iter.Valid(); iter.Next() { + expectedKey := expected2[i] + key, value := iter.Key(), iter.Value() + assert.EqualValues(t, key, expectedKey) + assert.EqualValues(t, value, []byte("test4")) + i += 1 + } + assert.Equal(t, len(expected), i) + + iter = iavlStore.ReverseSubspaceIterator([]byte{byte(255), byte(255)}) + expected2 = [][]byte{ + []byte{byte(255), byte(255), byte(255)}, + []byte{byte(255), byte(255), byte(1)}, + []byte{byte(255), byte(255), byte(0)}, + } + for i = 0; iter.Valid(); iter.Next() { + expectedKey := expected2[i] + key, value := iter.Key(), iter.Value() + assert.EqualValues(t, key, expectedKey) + assert.EqualValues(t, value, []byte("test4")) + i += 1 + } + assert.Equal(t, len(expected), i) } func TestIAVLStoreQuery(t *testing.T) { diff --git a/store/rootmultistore.go b/store/rootmultistore.go index 9be28967c..3e094712b 100644 --- a/store/rootmultistore.go +++ b/store/rootmultistore.go @@ -56,8 +56,9 @@ func (rs *rootMultiStore) MountStoreWithDB(key StoreKey, typ StoreType, db dbm.D panic(fmt.Sprintf("rootMultiStore duplicate store key %v", key)) } rs.storesParams[key] = storeParams{ - db: db, + key: key, typ: typ, + db: db, } rs.keysByName[key.Name()] = key } @@ -244,9 +245,11 @@ func parsePath(path string) (storeName string, subpath string, err sdk.Error) { //---------------------------------------- func (rs *rootMultiStore) loadCommitStoreFromParams(id CommitID, params storeParams) (store CommitStore, err error) { - db := rs.db + var db dbm.DB if params.db != nil { - db = params.db + db = dbm.NewPrefixDB(params.db, []byte("s/_/")) + } else { + db = dbm.NewPrefixDB(rs.db, []byte("s/k:"+params.key.Name()+"/")) } switch params.typ { case sdk.StoreTypeMulti: @@ -276,6 +279,7 @@ func (rs *rootMultiStore) nameToKey(name string) StoreKey { // storeParams type storeParams struct { + key StoreKey db dbm.DB typ StoreType } @@ -375,10 +379,11 @@ func commitStores(version int64, storeMap map[StoreKey]CommitStore) commitInfo { storeInfos = append(storeInfos, si) } - return commitInfo{ + ci := commitInfo{ Version: version, StoreInfos: storeInfos, } + return ci } // Gets commitInfo from disk. diff --git a/store/rootmultistore_test.go b/store/rootmultistore_test.go index 333f0f5af..3796bd477 100644 --- a/store/rootmultistore_test.go +++ b/store/rootmultistore_test.go @@ -11,17 +11,22 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) +const useDebugDB = false + func TestMultistoreCommitLoad(t *testing.T) { - db := dbm.NewMemDB() + var db dbm.DB = dbm.NewMemDB() + if useDebugDB { + db = dbm.NewDebugDB("CMS", db) + } store := newMultiStoreWithMounts(db) err := store.LoadLatestVersion() assert.Nil(t, err) - // new store has empty last commit + // New store has empty last commit. commitID := CommitID{} checkStore(t, store, commitID, commitID) - // make sure we can get stores by name + // Make sure we can get stores by name. s1 := store.getStoreByName("store1") assert.NotNil(t, s1) s3 := store.getStoreByName("store3") @@ -29,7 +34,7 @@ func TestMultistoreCommitLoad(t *testing.T) { s77 := store.getStoreByName("store77") assert.Nil(t, s77) - // make a few commits and check them + // Make a few commits and check them. nCommits := int64(3) for i := int64(0); i < nCommits; i++ { commitID = store.Commit() @@ -37,19 +42,19 @@ func TestMultistoreCommitLoad(t *testing.T) { checkStore(t, store, expectedCommitID, commitID) } - // Load the latest multistore again and check version + // Load the latest multistore again and check version. store = newMultiStoreWithMounts(db) err = store.LoadLatestVersion() assert.Nil(t, err) commitID = getExpectedCommitID(store, nCommits) checkStore(t, store, commitID, commitID) - // commit and check version + // Commit and check version. commitID = store.Commit() expectedCommitID := getExpectedCommitID(store, nCommits+1) checkStore(t, store, expectedCommitID, commitID) - // Load an older multistore and check version + // Load an older multistore and check version. ver := nCommits - 1 store = newMultiStoreWithMounts(db) err = store.LoadVersion(ver) @@ -62,8 +67,8 @@ func TestMultistoreCommitLoad(t *testing.T) { expectedCommitID = getExpectedCommitID(store, ver+1) checkStore(t, store, expectedCommitID, commitID) - // XXX: confirm old commit is overwritten and - // we have rolled back LatestVersion + // XXX: confirm old commit is overwritten and we have rolled back + // LatestVersion store = newMultiStoreWithMounts(db) err = store.LoadLatestVersion() assert.Nil(t, err) @@ -104,23 +109,23 @@ func TestMultiStoreQuery(t *testing.T) { cid := multi.Commit() - // make sure we can get by name + // Make sure we can get by name. garbage := multi.getStoreByName("bad-name") assert.Nil(t, garbage) - // set and commit data in one store + // Set and commit data in one store. store1 := multi.getStoreByName("store1").(KVStore) store1.Set(k, v) - // and another + // ... and another. store2 := multi.getStoreByName("store2").(KVStore) store2.Set(k2, v2) - // commit the multistore + // Commit the multistore. cid = multi.Commit() ver := cid.Version - // bad path + // Test bad path. query := abci.RequestQuery{Path: "/key", Data: k, Height: ver} qres := multi.Query(query) assert.Equal(t, uint32(sdk.CodeUnknownRequest), qres.Code) @@ -129,25 +134,25 @@ func TestMultiStoreQuery(t *testing.T) { qres = multi.Query(query) assert.Equal(t, uint32(sdk.CodeUnknownRequest), qres.Code) - // invalid store name + // Test invalid store name. query.Path = "/garbage/key" qres = multi.Query(query) assert.Equal(t, uint32(sdk.CodeUnknownRequest), qres.Code) - // valid query with data + // Test valid query with data. query.Path = "/store1/key" qres = multi.Query(query) assert.Equal(t, uint32(sdk.CodeOK), qres.Code) assert.Equal(t, v, qres.Value) - // valid but empty + // Test valid but empty query. query.Path = "/store2/key" query.Prove = true qres = multi.Query(query) assert.Equal(t, uint32(sdk.CodeOK), qres.Code) assert.Nil(t, qres.Value) - // store2 data + // Test store2 data. query.Data = k2 qres = multi.Query(query) assert.Equal(t, uint32(sdk.CodeOK), qres.Code) diff --git a/types/coin.go b/types/coin.go index ab7d863c1..8a80bee22 100644 --- a/types/coin.go +++ b/types/coin.go @@ -110,7 +110,7 @@ func (coins Coins) IsValid() bool { // Plus combines two sets of coins // CONTRACT: Plus will never return Coins where one Coin has a 0 amount. func (coins Coins) Plus(coinsB Coins) Coins { - sum := []Coin{} + sum := ([]Coin)(nil) indexA, indexB := 0, 0 lenA, lenB := len(coins), len(coinsB) for { diff --git a/types/coin_test.go b/types/coin_test.go index 19929e8c7..eb9f5e087 100644 --- a/types/coin_test.go +++ b/types/coin_test.go @@ -201,8 +201,8 @@ func TestPlusCoins(t *testing.T) { }{ {Coins{{"A", 1}, {"B", 1}}, Coins{{"A", 1}, {"B", 1}}, Coins{{"A", 2}, {"B", 2}}}, {Coins{{"A", 0}, {"B", 1}}, Coins{{"A", 0}, {"B", 0}}, Coins{{"B", 1}}}, - {Coins{{"A", 0}, {"B", 0}}, Coins{{"A", 0}, {"B", 0}}, Coins{}}, - {Coins{{"A", 1}, {"B", 0}}, Coins{{"A", -1}, {"B", 0}}, Coins{}}, + {Coins{{"A", 0}, {"B", 0}}, Coins{{"A", 0}, {"B", 0}}, Coins(nil)}, + {Coins{{"A", 1}, {"B", 0}}, Coins{{"A", -1}, {"B", 0}}, Coins(nil)}, {Coins{{"A", -1}, {"B", 0}}, Coins{{"A", 0}, {"B", 0}}, Coins{{"A", -1}}}, } diff --git a/types/context.go b/types/context.go index 3c90b016a..8c91175bc 100644 --- a/types/context.go +++ b/types/context.go @@ -171,6 +171,14 @@ func (c Context) WithTxBytes(txBytes []byte) Context { return c.withValue(contextKeyTxBytes, txBytes) } +// Cache the multistore and return a new cached context. The cached context is +// written to the context when writeCache is called. +func (c Context) CacheContext() (cc Context, writeCache func()) { + cms := c.multiStore().CacheMultiStore() + cc = c.WithMultiStore(cms) + return cc, cms.Write +} + //---------------------------------------- // thePast diff --git a/types/context_test.go b/types/context_test.go index 36d8099b9..b40e79dc2 100644 --- a/types/context_test.go +++ b/types/context_test.go @@ -3,6 +3,11 @@ package types_test import ( "testing" + "github.com/stretchr/testify/assert" + + dbm "github.com/tendermint/tmlibs/db" + + "github.com/cosmos/cosmos-sdk/store" "github.com/cosmos/cosmos-sdk/types" abci "github.com/tendermint/abci/types" ) @@ -18,3 +23,39 @@ func TestContextGetOpShouldNeverPanic(t *testing.T) { _, _ = ctx.GetOp(index) } } + +func defaultContext(key types.StoreKey) types.Context { + db := dbm.NewMemDB() + cms := store.NewCommitMultiStore(db) + cms.MountStoreWithDB(key, types.StoreTypeIAVL, db) + cms.LoadLatestVersion() + ctx := types.NewContext(cms, abci.Header{}, false, nil) + return ctx +} + +func TestCacheContext(t *testing.T) { + key := types.NewKVStoreKey(t.Name()) + k1 := []byte("hello") + v1 := []byte("world") + k2 := []byte("key") + v2 := []byte("value") + + ctx := defaultContext(key) + store := ctx.KVStore(key) + store.Set(k1, v1) + assert.Equal(t, v1, store.Get(k1)) + assert.Nil(t, store.Get(k2)) + + cctx, write := ctx.CacheContext() + cstore := cctx.KVStore(key) + assert.Equal(t, v1, cstore.Get(k1)) + assert.Nil(t, cstore.Get(k2)) + + cstore.Set(k2, v2) + assert.Equal(t, v2, cstore.Get(k2)) + assert.Nil(t, store.Get(k2)) + + write() + + assert.Equal(t, v2, store.Get(k2)) +} diff --git a/types/handler.go b/types/handler.go index 129f42647..679a3b1a7 100644 --- a/types/handler.go +++ b/types/handler.go @@ -3,5 +3,8 @@ package types // core function variable which application runs for transactions type Handler func(ctx Context, msg Msg) Result +// core function variable which application runs to handle fees +type FeeHandler func(ctx Context, tx Tx, fee Coins) + // If newCtx.IsZero(), ctx is used instead. type AnteHandler func(ctx Context, tx Tx) (newCtx Context, result Result, abort bool) diff --git a/types/store.go b/types/store.go index ef2e9154b..7b73570ca 100644 --- a/types/store.go +++ b/types/store.go @@ -111,6 +111,14 @@ type KVStore interface { // CONTRACT: No writes may happen within a domain while an iterator exists over it. ReverseIterator(start, end []byte) Iterator + // Iterator over all the keys with a certain prefix in ascending order. + // CONTRACT: No writes may happen within a domain while an iterator exists over it. + SubspaceIterator(prefix []byte) Iterator + + // Iterator over all the keys with a certain prefix in descending order. + // CONTRACT: No writes may happen within a domain while an iterator exists over it. + ReverseSubspaceIterator(prefix []byte) Iterator + // TODO Not yet implemented. // CreateSubKVStore(key *storeKey) (KVStore, error) @@ -222,3 +230,29 @@ func (key *KVStoreKey) Name() string { func (key *KVStoreKey) String() string { return fmt.Sprintf("KVStoreKey{%p, %s}", key, key.name) } + +// PrefixEndBytes returns the []byte that would end a +// range query for all []byte with a certain prefix +// Deals with last byte of prefix being FF without overflowing +func PrefixEndBytes(prefix []byte) []byte { + if prefix == nil { + return nil + } + + end := make([]byte, len(prefix)) + copy(end, prefix) + + for { + if end[len(end)-1] != byte(255) { + end[len(end)-1]++ + break + } else { + end = end[:len(end)-1] + if len(end) == 0 { + end = nil + break + } + } + } + return end +} diff --git a/types/store_test.go b/types/store_test.go new file mode 100644 index 000000000..43dd1f5d3 --- /dev/null +++ b/types/store_test.go @@ -0,0 +1,29 @@ +package types + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestPrefixEndBytes(t *testing.T) { + assert := assert.New(t) + + var testCases = []struct { + prefix []byte + expected []byte + }{ + {[]byte{byte(55), byte(255), byte(255), byte(0)}, []byte{byte(55), byte(255), byte(255), byte(1)}}, + {[]byte{byte(55), byte(255), byte(255), byte(15)}, []byte{byte(55), byte(255), byte(255), byte(16)}}, + {[]byte{byte(55), byte(200), byte(255)}, []byte{byte(55), byte(201)}}, + {[]byte{byte(55), byte(255), byte(255)}, []byte{byte(56)}}, + {[]byte{byte(255), byte(255), byte(255)}, nil}, + {[]byte{byte(255)}, nil}, + {nil, nil}, + } + + for _, test := range testCases { + end := PrefixEndBytes(test.prefix) + assert.Equal(test.expected, end) + } +} diff --git a/version/version.go b/version/version.go index 119e0ca80..957af26af 100644 --- a/version/version.go +++ b/version/version.go @@ -6,10 +6,10 @@ package version // TODO improve const Maj = "0" -const Min = "14" -const Fix = "1" +const Min = "15" +const Fix = "0" -const Version = "0.14.1" +const Version = "0.15.0" // GitCommit set by build flags var GitCommit = "" diff --git a/wire/wire.go b/wire/wire.go index e53d5e195..32c82a676 100644 --- a/wire/wire.go +++ b/wire/wire.go @@ -2,54 +2,33 @@ package wire import ( "bytes" - "reflect" + "encoding/json" - "github.com/tendermint/go-wire" + "github.com/tendermint/go-amino" + "github.com/tendermint/go-crypto" ) -type Codec struct{} +type Codec = amino.Codec func NewCodec() *Codec { - return &Codec{} + cdc := amino.NewCodec() + return cdc } -func (cdc *Codec) MarshalBinary(o interface{}) ([]byte, error) { - w, n, err := new(bytes.Buffer), new(int), new(error) - wire.WriteBinary(o, w, n, err) - return w.Bytes(), *err -} - -func (cdc *Codec) UnmarshalBinary(bz []byte, o interface{}) error { - r, n, err := bytes.NewBuffer(bz), new(int), new(error) - - rv := reflect.ValueOf(o) - if rv.Kind() == reflect.Ptr { - wire.ReadBinaryPtr(o, r, len(bz), n, err) - } else { - wire.ReadBinary(o, r, len(bz), n, err) - } - return *err -} - -func (cdc *Codec) MarshalJSON(o interface{}) ([]byte, error) { - w, n, err := new(bytes.Buffer), new(int), new(error) - wire.WriteJSON(o, w, n, err) - return w.Bytes(), *err -} - -func (cdc *Codec) UnmarshalJSON(bz []byte, o interface{}) (err error) { - - rv := reflect.ValueOf(o) - if rv.Kind() == reflect.Ptr { - wire.ReadJSONPtr(o, bz, &err) - } else { - wire.ReadJSON(o, bz, &err) - } - return err -} - -//---------------------------------------------- - func RegisterCrypto(cdc *Codec) { - // TODO + crypto.RegisterAmino(cdc) +} + +func MarshalJSONIndent(cdc *Codec, obj interface{}) ([]byte, error) { + bz, err := cdc.MarshalJSON(obj) + if err != nil { + return nil, err + } + + var out bytes.Buffer + err = json.Indent(&out, bz, "", " ") + if err != nil { + return nil, err + } + return out.Bytes(), nil } diff --git a/x/auth/ante.go b/x/auth/ante.go index a5ab83bcb..c7af7e2d9 100644 --- a/x/auth/ante.go +++ b/x/auth/ante.go @@ -11,7 +11,7 @@ import ( // NewAnteHandler returns an AnteHandler that checks // and increments sequence numbers, checks signatures, // and deducts fees from the first signer. -func NewAnteHandler(accountMapper sdk.AccountMapper) sdk.AnteHandler { +func NewAnteHandler(accountMapper sdk.AccountMapper, feeHandler sdk.FeeHandler) sdk.AnteHandler { return func( ctx sdk.Context, tx sdk.Tx, ) (_ sdk.Context, _ sdk.Result, abort bool) { @@ -74,6 +74,7 @@ func NewAnteHandler(accountMapper sdk.AccountMapper) sdk.AnteHandler { // TODO: min fee if !fee.Amount.IsZero() { signerAcc, res = deductFees(signerAcc, fee) + feeHandler(ctx, tx, fee.Amount) if !res.IsOK() { return ctx, res, true } @@ -118,9 +119,9 @@ func processSig( // If pubkey is not known for account, // set it from the StdSignature. pubKey := acc.GetPubKey() - if pubKey.Empty() { + if pubKey == nil { pubKey = sig.PubKey - if pubKey.Empty() { + if pubKey == nil { return nil, sdk.ErrInvalidPubKey("PubKey not found").Result() } if !bytes.Equal(pubKey.Address(), addr) { @@ -156,3 +157,7 @@ func deductFees(acc sdk.Account, fee sdk.StdFee) (sdk.Account, sdk.Result) { acc.SetCoins(newCoins) return acc, sdk.Result{} } + +// BurnFeeHandler burns all fees (decreasing total supply) +func BurnFeeHandler(ctx sdk.Context, tx sdk.Tx, fee sdk.Coins) { +} diff --git a/x/auth/ante_test.go b/x/auth/ante_test.go index fd94145dd..58633ff9a 100644 --- a/x/auth/ante_test.go +++ b/x/auth/ante_test.go @@ -3,11 +3,13 @@ package auth import ( "testing" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" abci "github.com/tendermint/abci/types" crypto "github.com/tendermint/go-crypto" + + sdk "github.com/cosmos/cosmos-sdk/types" + wire "github.com/cosmos/cosmos-sdk/wire" ) func newTestMsg(addrs ...sdk.Address) *sdk.TestMsg { @@ -31,7 +33,7 @@ func newCoins() sdk.Coins { func privAndAddr() (crypto.PrivKey, sdk.Address) { priv := crypto.GenPrivKeyEd25519() addr := priv.PubKey().Address() - return priv.Wrap(), addr + return priv, addr } // run the tx through the anteHandler and ensure its valid @@ -67,8 +69,10 @@ func newTestTxWithSignBytes(msg sdk.Msg, privs []crypto.PrivKey, seqs []int64, f func TestAnteHandlerSigErrors(t *testing.T) { // setup ms, capKey := setupMultiStore() - mapper := NewAccountMapper(capKey, &BaseAccount{}) - anteHandler := NewAnteHandler(mapper) + cdc := wire.NewCodec() + RegisterBaseAccount(cdc) + mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) + anteHandler := NewAnteHandler(mapper, BurnFeeHandler) ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil) // keys and addresses @@ -106,8 +110,10 @@ func TestAnteHandlerSigErrors(t *testing.T) { func TestAnteHandlerSequences(t *testing.T) { // setup ms, capKey := setupMultiStore() - mapper := NewAccountMapper(capKey, &BaseAccount{}) - anteHandler := NewAnteHandler(mapper) + cdc := wire.NewCodec() + RegisterBaseAccount(cdc) + mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) + anteHandler := NewAnteHandler(mapper, BurnFeeHandler) ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil) // keys and addresses @@ -170,8 +176,10 @@ func TestAnteHandlerSequences(t *testing.T) { func TestAnteHandlerFees(t *testing.T) { // setup ms, capKey := setupMultiStore() - mapper := NewAccountMapper(capKey, &BaseAccount{}) - anteHandler := NewAnteHandler(mapper) + cdc := wire.NewCodec() + RegisterBaseAccount(cdc) + mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) + anteHandler := NewAnteHandler(mapper, BurnFeeHandler) ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil) // keys and addresses @@ -205,8 +213,10 @@ func TestAnteHandlerFees(t *testing.T) { func TestAnteHandlerBadSignBytes(t *testing.T) { // setup ms, capKey := setupMultiStore() - mapper := NewAccountMapper(capKey, &BaseAccount{}) - anteHandler := NewAnteHandler(mapper) + cdc := wire.NewCodec() + RegisterBaseAccount(cdc) + mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) + anteHandler := NewAnteHandler(mapper, BurnFeeHandler) ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil) // keys and addresses @@ -278,8 +288,10 @@ func TestAnteHandlerBadSignBytes(t *testing.T) { func TestAnteHandlerSetPubKey(t *testing.T) { // setup ms, capKey := setupMultiStore() - mapper := NewAccountMapper(capKey, &BaseAccount{}) - anteHandler := NewAnteHandler(mapper) + cdc := wire.NewCodec() + RegisterBaseAccount(cdc) + mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) + anteHandler := NewAnteHandler(mapper, BurnFeeHandler) ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil) // keys and addresses @@ -310,16 +322,16 @@ func TestAnteHandlerSetPubKey(t *testing.T) { msg = newTestMsg(addr2) tx = newTestTx(ctx, msg, privs, seqs, fee) sigs := tx.GetSignatures() - sigs[0].PubKey = crypto.PubKey{} + sigs[0].PubKey = nil checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeInvalidPubKey) acc2 = mapper.GetAccount(ctx, addr2) - assert.True(t, acc2.GetPubKey().Empty()) + assert.Nil(t, acc2.GetPubKey()) // test invalid signature and public key tx = newTestTx(ctx, msg, privs, seqs, fee) checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeInvalidPubKey) acc2 = mapper.GetAccount(ctx, addr2) - assert.True(t, acc2.GetPubKey().Empty()) + assert.Nil(t, acc2.GetPubKey()) } diff --git a/x/auth/baseaccount.go b/x/auth/baseaccount.go index 23123f994..a5f33c81d 100644 --- a/x/auth/baseaccount.go +++ b/x/auth/baseaccount.go @@ -61,7 +61,7 @@ func (acc BaseAccount) GetPubKey() crypto.PubKey { // Implements sdk.Account. func (acc *BaseAccount) SetPubKey(pubKey crypto.PubKey) error { - if !acc.PubKey.Empty() { + if acc.PubKey != nil { return errors.New("cannot override BaseAccount pubkey") } acc.PubKey = pubKey @@ -93,7 +93,9 @@ func (acc *BaseAccount) SetSequence(seq int64) error { //---------------------------------------- // Wire -func RegisterWireBaseAccount(cdc *wire.Codec) { - // Register crypto.[PubKey,PrivKey,Signature] types. +// Most users shouldn't use this, but this comes handy for tests. +func RegisterBaseAccount(cdc *wire.Codec) { + cdc.RegisterInterface((*sdk.Account)(nil), nil) + cdc.RegisterConcrete(&BaseAccount{}, "cosmos-sdk/BaseAccount", nil) wire.RegisterCrypto(cdc) } diff --git a/x/auth/baseaccount_test.go b/x/auth/baseaccount_test.go index b2f5b54ae..24b3e3673 100644 --- a/x/auth/baseaccount_test.go +++ b/x/auth/baseaccount_test.go @@ -15,7 +15,7 @@ func keyPubAddr() (crypto.PrivKey, crypto.PubKey, sdk.Address) { key := crypto.GenPrivKeyEd25519() pub := key.PubKey() addr := pub.Address() - return key.Wrap(), pub, addr + return key, pub, addr } func TestBaseAccountAddressPubKey(t *testing.T) { @@ -25,7 +25,7 @@ func TestBaseAccountAddressPubKey(t *testing.T) { // check the address (set) and pubkey (not set) assert.EqualValues(t, addr1, acc.GetAddress()) - assert.EqualValues(t, crypto.PubKey{}, acc.GetPubKey()) + assert.EqualValues(t, nil, acc.GetPubKey()) // can't override address err := acc.SetAddress(addr2) diff --git a/x/auth/commands/account.go b/x/auth/commands/account.go index b87b95769..56f441f35 100644 --- a/x/auth/commands/account.go +++ b/x/auth/commands/account.go @@ -2,7 +2,6 @@ package commands import ( "encoding/hex" - "encoding/json" "fmt" "github.com/pkg/errors" @@ -11,7 +10,6 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" - "github.com/cosmos/cosmos-sdk/x/auth" ) // GetAccountCmd for the auth.BaseAccount type @@ -20,9 +18,9 @@ func GetAccountCmdDefault(storeName string, cdc *wire.Codec) *cobra.Command { } func GetAccountDecoder(cdc *wire.Codec) sdk.AccountDecoder { - return func(accBytes []byte) (sdk.Account, error) { - acct := new(auth.BaseAccount) - err := cdc.UnmarshalBinary(accBytes, &acct) + return func(accBytes []byte) (acct sdk.Account, err error) { + // acct := new(auth.BaseAccount) + err = cdc.UnmarshalBinaryBare(accBytes, &acct) if err != nil { panic(err) } @@ -78,7 +76,7 @@ func (c commander) getAccountCmd(cmd *cobra.Command, args []string) error { } // print out whole account - output, err := json.MarshalIndent(account, "", " ") + output, err := wire.MarshalJSONIndent(c.cdc, account) if err != nil { return err } diff --git a/x/auth/mapper.go b/x/auth/mapper.go index 13fe9a844..7bc23aee1 100644 --- a/x/auth/mapper.go +++ b/x/auth/mapper.go @@ -1,12 +1,9 @@ package auth import ( - "bytes" "fmt" "reflect" - oldwire "github.com/tendermint/go-wire" - sdk "github.com/cosmos/cosmos-sdk/types" wire "github.com/cosmos/cosmos-sdk/wire" ) @@ -16,7 +13,7 @@ var _ sdk.AccountMapper = (*sealedAccountMapper)(nil) // Implements sdk.AccountMapper. // This AccountMapper encodes/decodes accounts using the -// go-wire (binary) encoding/decoding library. +// go-amino (binary) encoding/decoding library. type accountMapper struct { // The (unexposed) key used to access the store from the Context. @@ -30,9 +27,8 @@ type accountMapper struct { } // NewAccountMapper returns a new sdk.AccountMapper that -// uses go-wire to (binary) encode and decode concrete sdk.Accounts. -func NewAccountMapper(key sdk.StoreKey, proto sdk.Account) accountMapper { - cdc := wire.NewCodec() +// uses go-amino to (binary) encode and decode concrete sdk.Accounts. +func NewAccountMapper(cdc *wire.Codec, key sdk.StoreKey, proto sdk.Account) accountMapper { return accountMapper{ key: key, proto: proto, @@ -40,21 +36,7 @@ func NewAccountMapper(key sdk.StoreKey, proto sdk.Account) accountMapper { } } -// Create and return a sealed account mapper -func NewAccountMapperSealed(key sdk.StoreKey, proto sdk.Account) sealedAccountMapper { - cdc := wire.NewCodec() - am := accountMapper{ - key: key, - proto: proto, - cdc: cdc, - } - RegisterWireBaseAccount(cdc) - - // make accountMapper's WireCodec() inaccessible, return - return am.Seal() -} - -// Returns the go-wire codec. You may need to register interfaces +// Returns the go-amino codec. You may need to register interfaces // and concrete types here, if your app's sdk.Account // implementation includes interface fields. // NOTE: It is not secure to expose the codec, so check out @@ -103,7 +85,7 @@ type sealedAccountMapper struct { } // There's no way for external modules to mutate the -// sam.accountMapper.ctx from here, even with reflection. +// sam.accountMapper.cdc from here, even with reflection. func (sam sealedAccountMapper) WireCodec() *wire.Codec { panic("accountMapper is sealed") } @@ -111,22 +93,6 @@ func (sam sealedAccountMapper) WireCodec() *wire.Codec { //---------------------------------------- // misc. -// NOTE: currently unused -func (am accountMapper) clonePrototypePtr() interface{} { - protoRt := reflect.TypeOf(am.proto) - if protoRt.Kind() == reflect.Ptr { - protoErt := protoRt.Elem() - if protoErt.Kind() != reflect.Struct { - panic("accountMapper requires a struct proto sdk.Account, or a pointer to one") - } - protoRv := reflect.New(protoErt) - return protoRv.Interface() - } else { - protoRv := reflect.New(protoRt) - return protoRv.Interface() - } -} - // Creates a new struct (or pointer to struct) from am.proto. func (am accountMapper) clonePrototype() sdk.Account { protoRt := reflect.TypeOf(am.proto) @@ -152,34 +118,17 @@ func (am accountMapper) clonePrototype() sdk.Account { } func (am accountMapper) encodeAccount(acc sdk.Account) []byte { - bz, err := am.cdc.MarshalBinary(acc) + bz, err := am.cdc.MarshalBinaryBare(acc) if err != nil { panic(err) } return bz } -func (am accountMapper) decodeAccount(bz []byte) sdk.Account { - // ... old go-wire ... - r, n, err := bytes.NewBuffer(bz), new(int), new(error) - accI := oldwire.ReadBinary(struct{ sdk.Account }{}, r, len(bz), n, err) - if *err != nil { - panic(*err) +func (am accountMapper) decodeAccount(bz []byte) (acc sdk.Account) { + err := am.cdc.UnmarshalBinaryBare(bz, &acc) + if err != nil { + panic(err) } - - acc := accI.(struct{ sdk.Account }).Account - return acc - - /* - accPtr := am.clonePrototypePtr() - err := am.cdc.UnmarshalBinary(bz, accPtr) - if err != nil { - panic(err) - } - if reflect.ValueOf(am.proto).Kind() == reflect.Ptr { - return reflect.ValueOf(accPtr).Interface().(sdk.Account) - } else { - return reflect.ValueOf(accPtr).Elem().Interface().(sdk.Account) - } - */ + return } diff --git a/x/auth/mapper_test.go b/x/auth/mapper_test.go index 4ac96c381..030207db2 100644 --- a/x/auth/mapper_test.go +++ b/x/auth/mapper_test.go @@ -6,12 +6,11 @@ import ( "github.com/stretchr/testify/assert" abci "github.com/tendermint/abci/types" - crypto "github.com/tendermint/go-crypto" - oldwire "github.com/tendermint/go-wire" dbm "github.com/tendermint/tmlibs/db" "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" + wire "github.com/cosmos/cosmos-sdk/wire" ) func setupMultiStore() (sdk.MultiStore, *sdk.KVStoreKey) { @@ -20,22 +19,17 @@ func setupMultiStore() (sdk.MultiStore, *sdk.KVStoreKey) { ms := store.NewCommitMultiStore(db) ms.MountStoreWithDB(capKey, sdk.StoreTypeIAVL, db) ms.LoadLatestVersion() - - // wire registration while we're at it ... TODO - var _ = oldwire.RegisterInterface( - struct{ sdk.Account }{}, - oldwire.ConcreteType{&BaseAccount{}, 0x1}, - ) - return ms, capKey } func TestAccountMapperGetSet(t *testing.T) { ms, capKey := setupMultiStore() + cdc := wire.NewCodec() + RegisterBaseAccount(cdc) // make context and mapper ctx := sdk.NewContext(ms, abci.Header{}, false, nil) - mapper := NewAccountMapper(capKey, &BaseAccount{}) + mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) addr := sdk.Address([]byte("some-address")) @@ -47,7 +41,7 @@ func TestAccountMapperGetSet(t *testing.T) { acc = mapper.NewAccountWithAddress(ctx, addr) assert.NotNil(t, acc) assert.Equal(t, addr, acc.GetAddress()) - assert.EqualValues(t, crypto.PubKey{}, acc.GetPubKey()) + assert.EqualValues(t, nil, acc.GetPubKey()) assert.EqualValues(t, 0, acc.GetSequence()) // NewAccount doesn't call Set, so it's still nil @@ -66,16 +60,14 @@ func TestAccountMapperGetSet(t *testing.T) { func TestAccountMapperSealed(t *testing.T) { _, capKey := setupMultiStore() + cdc := wire.NewCodec() + RegisterBaseAccount(cdc) // normal mapper exposes the wire codec - mapper := NewAccountMapper(capKey, &BaseAccount{}) + mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) assert.NotNil(t, mapper.WireCodec()) // seal mapper, should panic when we try to get the codec mapperSealed := mapper.Seal() assert.Panics(t, func() { mapperSealed.WireCodec() }) - - // another way to get a sealed mapper - mapperSealed = NewAccountMapperSealed(capKey, &BaseAccount{}) - assert.Panics(t, func() { mapperSealed.WireCodec() }) } diff --git a/x/auth/rest/query.go b/x/auth/rest/query.go index 5430a77ff..c401fe47f 100644 --- a/x/auth/rest/query.go +++ b/x/auth/rest/query.go @@ -2,7 +2,6 @@ package rest import ( "encoding/hex" - "encoding/json" "fmt" "net/http" @@ -56,7 +55,7 @@ func QueryAccountRequestHandler(storeName string, cdc *wire.Codec, decoder sdk.A } // print out whole account - output, err := json.MarshalIndent(account, "", " ") + output, err := cdc.MarshalJSON(account) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(fmt.Sprintf("Could't marshall query result. Error: %s", err.Error()))) diff --git a/x/bank/commands/sendtx.go b/x/bank/commands/sendtx.go index ee4625eac..56048262d 100644 --- a/x/bank/commands/sendtx.go +++ b/x/bank/commands/sendtx.go @@ -7,12 +7,11 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" + authcmd "github.com/cosmos/cosmos-sdk/x/auth/commands" "github.com/cosmos/cosmos-sdk/x/bank" - cryptokeys "github.com/tendermint/go-crypto/keys" ) const ( @@ -38,7 +37,7 @@ type Commander struct { } func (c Commander) sendTxCmd(cmd *cobra.Command, args []string) error { - ctx := context.NewCoreContextFromViper() + ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(c.Cdc)) // get the from address from, err := ctx.GetFromAddress() @@ -64,6 +63,12 @@ func (c Commander) sendTxCmd(cmd *cobra.Command, args []string) error { // build message msg := BuildMsg(from, to, coins) + // default to next sequence number if none provided + ctx, err = context.EnsureSequence(ctx) + if err != nil { + return err + } + // build and sign the transaction, then broadcast to Tendermint res, err := ctx.SignBuildBroadcast(ctx.FromAddressName, msg, c.Cdc) if err != nil { @@ -80,29 +85,3 @@ func BuildMsg(from sdk.Address, to sdk.Address, coins sdk.Coins) sdk.Msg { msg := bank.NewSendMsg([]bank.Input{input}, []bank.Output{output}) return msg } - -func (c Commander) SignMessage(msg sdk.Msg, kb cryptokeys.Keybase, accountName string, password string) ([]byte, error) { - // sign and build - bz := msg.GetSignBytes() - sig, pubkey, err := kb.Sign(accountName, password, bz) - if err != nil { - return nil, err - } - sigs := []sdk.StdSignature{{ - PubKey: pubkey, - Signature: sig, - Sequence: viper.GetInt64(client.FlagName), - }} - - // TODO: fees - var fee sdk.StdFee - - // marshal bytes - tx := sdk.NewStdTx(msg, fee, sigs) - - txBytes, err := c.Cdc.MarshalBinary(tx) - if err != nil { - return nil, err - } - return txBytes, nil -} diff --git a/x/ibc/commands/ibctx.go b/x/ibc/commands/ibctx.go index 689a98318..d17b40b21 100644 --- a/x/ibc/commands/ibctx.go +++ b/x/ibc/commands/ibctx.go @@ -13,6 +13,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" wire "github.com/cosmos/cosmos-sdk/wire" + authcmd "github.com/cosmos/cosmos-sdk/x/auth/commands" "github.com/cosmos/cosmos-sdk/x/ibc" ) @@ -39,7 +40,7 @@ type sendCommander struct { } func (c sendCommander) sendIBCTransfer(cmd *cobra.Command, args []string) error { - ctx := context.NewCoreContextFromViper() + ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(c.cdc)) // get the from address from, err := ctx.GetFromAddress() @@ -53,6 +54,12 @@ func (c sendCommander) sendIBCTransfer(cmd *cobra.Command, args []string) error return err } + // default to next sequence number if none provided + ctx, err = context.EnsureSequence(ctx) + if err != nil { + return err + } + // get password res, err := ctx.SignBuildBroadcast(ctx.FromAddressName, msg, c.cdc) if err != nil { diff --git a/x/ibc/ibc_test.go b/x/ibc/ibc_test.go index 1e0431147..db172a5ca 100644 --- a/x/ibc/ibc_test.go +++ b/x/ibc/ibc_test.go @@ -7,7 +7,6 @@ import ( abci "github.com/tendermint/abci/types" "github.com/tendermint/go-crypto" - oldwire "github.com/tendermint/go-wire" dbm "github.com/tendermint/tmlibs/db" "github.com/cosmos/cosmos-sdk/store" @@ -33,39 +32,25 @@ func newAddress() crypto.Address { } func getCoins(ck bank.CoinKeeper, ctx sdk.Context, addr crypto.Address) (sdk.Coins, sdk.Error) { - zero := sdk.Coins{} + zero := sdk.Coins(nil) return ck.AddCoins(ctx, addr, zero) } -// custom tx codec -// TODO: use new go-wire func makeCodec() *wire.Codec { + var cdc = wire.NewCodec() - const msgTypeSend = 0x1 - const msgTypeIssue = 0x2 - const msgTypeQuiz = 0x3 - const msgTypeSetTrend = 0x4 - const msgTypeIBCTransferMsg = 0x5 - const msgTypeIBCReceiveMsg = 0x6 - var _ = oldwire.RegisterInterface( - struct{ sdk.Msg }{}, - oldwire.ConcreteType{bank.SendMsg{}, msgTypeSend}, - oldwire.ConcreteType{bank.IssueMsg{}, msgTypeIssue}, - oldwire.ConcreteType{IBCTransferMsg{}, msgTypeIBCTransferMsg}, - oldwire.ConcreteType{IBCReceiveMsg{}, msgTypeIBCReceiveMsg}, - ) + // Register Msgs + cdc.RegisterInterface((*sdk.Msg)(nil), nil) + cdc.RegisterConcrete(bank.SendMsg{}, "test/ibc/Send", nil) + cdc.RegisterConcrete(bank.IssueMsg{}, "test/ibc/Issue", nil) + cdc.RegisterConcrete(IBCTransferMsg{}, "test/ibc/IBCTransferMsg", nil) + cdc.RegisterConcrete(IBCReceiveMsg{}, "test/ibc/IBCReceiveMsg", nil) - const accTypeApp = 0x1 - var _ = oldwire.RegisterInterface( - struct{ sdk.Account }{}, - oldwire.ConcreteType{&auth.BaseAccount{}, accTypeApp}, - ) - cdc := wire.NewCodec() + // Register AppAccount + cdc.RegisterInterface((*sdk.Account)(nil), nil) + cdc.RegisterConcrete(&auth.BaseAccount{}, "test/ibc/Account", nil) + wire.RegisterCrypto(cdc) - // cdc.RegisterInterface((*sdk.Msg)(nil), nil) - // bank.RegisterWire(cdc) // Register bank.[SendMsg,IssueMsg] types. - // crypto.RegisterWire(cdc) // Register crypto.[PubKey,PrivKey,Signature] types. - // ibc.RegisterWire(cdc) // Register ibc.[IBCTransferMsg, IBCReceiveMsg] types. return cdc } @@ -75,13 +60,13 @@ func TestIBC(t *testing.T) { key := sdk.NewKVStoreKey("ibc") ctx := defaultContext(key) - am := auth.NewAccountMapper(key, &auth.BaseAccount{}) + am := auth.NewAccountMapper(cdc, key, &auth.BaseAccount{}) ck := bank.NewCoinKeeper(am) src := newAddress() dest := newAddress() chainid := "ibcchain" - zero := sdk.Coins{} + zero := sdk.Coins(nil) mycoins := sdk.Coins{sdk.Coin{"mycoin", 10}} coins, err := ck.AddCoins(ctx, src, mycoins) diff --git a/x/ibc/rest/transfer.go b/x/ibc/rest/transfer.go index fceac5567..1317730e7 100644 --- a/x/ibc/rest/transfer.go +++ b/x/ibc/rest/transfer.go @@ -2,7 +2,6 @@ package rest import ( "encoding/hex" - "encoding/json" "io/ioutil" "net/http" @@ -43,7 +42,7 @@ func TransferRequestHandler(cdc *wire.Codec, kb keys.Keybase) func(http.Response w.Write([]byte(err.Error())) return } - err = json.Unmarshal(body, &m) + err = cdc.UnmarshalJSON(body, &m) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(err.Error())) @@ -86,7 +85,7 @@ func TransferRequestHandler(cdc *wire.Codec, kb keys.Keybase) func(http.Response return } - output, err := json.MarshalIndent(res, "", " ") + output, err := cdc.MarshalJSON(res) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) diff --git a/x/simplestake/commands/commands.go b/x/simplestake/commands/commands.go index ce89801d8..ba6602028 100644 --- a/x/simplestake/commands/commands.go +++ b/x/simplestake/commands/commands.go @@ -12,6 +12,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" + authcmd "github.com/cosmos/cosmos-sdk/x/auth/commands" "github.com/cosmos/cosmos-sdk/x/simplestake" ) @@ -77,7 +78,7 @@ func (co commander) bondTxCmd(cmd *cobra.Command, args []string) error { var pubKeyEd crypto.PubKeyEd25519 copy(pubKeyEd[:], rawPubKey) - msg := simplestake.NewBondMsg(from, stake, pubKeyEd.Wrap()) + msg := simplestake.NewBondMsg(from, stake, pubKeyEd) return co.sendMsg(msg) } @@ -94,7 +95,14 @@ func (co commander) unbondTxCmd(cmd *cobra.Command, args []string) error { } func (co commander) sendMsg(msg sdk.Msg) error { - ctx := context.NewCoreContextFromViper() + ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(co.cdc)) + + // default to next sequence number if none provided + ctx, err := context.EnsureSequence(ctx) + if err != nil { + return err + } + res, err := ctx.SignBuildBroadcast(ctx.FromAddressName, msg, co.cdc) if err != nil { return err diff --git a/x/simplestake/keeper.go b/x/simplestake/keeper.go index e5892f3e2..7dcdbc20f 100644 --- a/x/simplestake/keeper.go +++ b/x/simplestake/keeper.go @@ -21,6 +21,7 @@ type Keeper struct { func NewKeeper(key sdk.StoreKey, coinKeeper bank.CoinKeeper) Keeper { cdc := wire.NewCodec() + wire.RegisterCrypto(cdc) return Keeper{ key: key, cdc: cdc, @@ -83,7 +84,7 @@ func (k Keeper) Bond(ctx sdk.Context, addr sdk.Address, pubKey crypto.PubKey, st func (k Keeper) Unbond(ctx sdk.Context, addr sdk.Address) (crypto.PubKey, int64, sdk.Error) { bi := k.getBondInfo(ctx, addr) if bi.isEmpty() { - return crypto.PubKey{}, 0, ErrInvalidUnbond() + return nil, 0, ErrInvalidUnbond() } k.deleteBondInfo(ctx, addr) @@ -121,7 +122,7 @@ func (k Keeper) bondWithoutCoins(ctx sdk.Context, addr sdk.Address, pubKey crypt func (k Keeper) unbondWithoutCoins(ctx sdk.Context, addr sdk.Address) (crypto.PubKey, int64, sdk.Error) { bi := k.getBondInfo(ctx, addr) if bi.isEmpty() { - return crypto.PubKey{}, 0, ErrInvalidUnbond() + return nil, 0, ErrInvalidUnbond() } k.deleteBondInfo(ctx, addr) diff --git a/x/simplestake/keeper_test.go b/x/simplestake/keeper_test.go index 9f2615590..7f9a120b9 100644 --- a/x/simplestake/keeper_test.go +++ b/x/simplestake/keeper_test.go @@ -13,6 +13,7 @@ import ( "github.com/cosmos/cosmos-sdk/store" 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/bank" ) @@ -55,10 +56,12 @@ func TestKeeperGetSet(t *testing.T) { func TestBonding(t *testing.T) { ms, authKey, capKey := setupMultiStore() + cdc := wire.NewCodec() + auth.RegisterBaseAccount(cdc) ctx := sdk.NewContext(ms, abci.Header{}, false, nil) - accountMapper := auth.NewAccountMapper(authKey, &auth.BaseAccount{}) + accountMapper := auth.NewAccountMapper(cdc, authKey, &auth.BaseAccount{}) coinKeeper := bank.NewCoinKeeper(accountMapper) stakeKeeper := NewKeeper(capKey, coinKeeper) addr := sdk.Address([]byte("some-address")) diff --git a/x/simplestake/msgs.go b/x/simplestake/msgs.go index 2ab0e1bad..9f4133484 100644 --- a/x/simplestake/msgs.go +++ b/x/simplestake/msgs.go @@ -34,7 +34,7 @@ func (msg BondMsg) ValidateBasic() sdk.Error { return ErrEmptyStake() } - if msg.PubKey.Empty() { + if msg.PubKey == nil { return sdk.ErrInvalidPubKey("BondMsg.PubKey must not be empty") } diff --git a/x/stake/commands/query.go b/x/stake/commands/query.go index 7bc6a8aa9..8cbb877ce 100644 --- a/x/stake/commands/query.go +++ b/x/stake/commands/query.go @@ -2,7 +2,6 @@ package commands import ( "encoding/hex" - "encoding/json" "fmt" "github.com/spf13/cobra" @@ -59,7 +58,7 @@ func GetCmdQueryCandidates(cdc *wire.Codec, storeName string) *cobra.Command { if err != nil { return err } - output, err := json.MarshalIndent(candidates, "", " ") + output, err := wire.MarshalJSONIndent(cdc, candidates) if err != nil { return err } @@ -101,7 +100,7 @@ func GetCmdQueryCandidate(cdc *wire.Codec, storeName string) *cobra.Command { if err != nil { return err } - output, err := json.MarshalIndent(candidate, "", " ") + output, err := wire.MarshalJSONIndent(cdc, candidate) if err != nil { return err } @@ -149,7 +148,7 @@ func GetCmdQueryDelegatorBond(cdc *wire.Codec, storeName string) *cobra.Command if err != nil { return err } - output, err := json.MarshalIndent(bond, "", " ") + output, err := wire.MarshalJSONIndent(cdc, bond) if err != nil { return err } @@ -193,7 +192,7 @@ func GetCmdQueryDelegatorBonds(cdc *wire.Codec, storeName string) *cobra.Command if err != nil { return err } - output, err := json.MarshalIndent(candidates, "", " ") + output, err := wire.MarshalJSONIndent(cdc, candidates) if err != nil { return err } diff --git a/x/stake/commands/tx.go b/x/stake/commands/tx.go index d1dec6dce..5cc9747b6 100644 --- a/x/stake/commands/tx.go +++ b/x/stake/commands/tx.go @@ -14,6 +14,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" + authcmd "github.com/cosmos/cosmos-sdk/x/auth/commands" "github.com/cosmos/cosmos-sdk/x/stake" ) @@ -92,7 +93,14 @@ func GetCmdDeclareCandidacy(cdc *wire.Codec) *cobra.Command { msg := stake.NewMsgDeclareCandidacy(candidateAddr, pk, amount, description) // build and sign the transaction, then broadcast to Tendermint - ctx := context.NewCoreContextFromViper() + ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) + + // default to next sequence number if none provided + ctx, err = context.EnsureSequence(ctx) + if err != nil { + return err + } + res, err := ctx.SignBuildBroadcast(ctx.FromAddressName, msg, cdc) if err != nil { return err @@ -129,7 +137,14 @@ func GetCmdEditCandidacy(cdc *wire.Codec) *cobra.Command { msg := stake.NewMsgEditCandidacy(candidateAddr, description) // build and sign the transaction, then broadcast to Tendermint - ctx := context.NewCoreContextFromViper() + ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) + + // default to next sequence number if none provided + ctx, err = context.EnsureSequence(ctx) + if err != nil { + return err + } + res, err := ctx.SignBuildBroadcast(ctx.FromAddressName, msg, cdc) if err != nil { return err @@ -165,7 +180,14 @@ func GetCmdDelegate(cdc *wire.Codec) *cobra.Command { msg := stake.NewMsgDelegate(delegatorAddr, candidateAddr, amount) // build and sign the transaction, then broadcast to Tendermint - ctx := context.NewCoreContextFromViper() + ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) + + // default to next sequence number if none provided + ctx, err = context.EnsureSequence(ctx) + if err != nil { + return err + } + res, err := ctx.SignBuildBroadcast(ctx.FromAddressName, msg, cdc) if err != nil { return err @@ -212,7 +234,14 @@ func GetCmdUnbond(cdc *wire.Codec) *cobra.Command { msg := stake.NewMsgUnbond(delegatorAddr, candidateAddr, sharesStr) // build and sign the transaction, then broadcast to Tendermint - ctx := context.NewCoreContextFromViper() + ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) + + // default to next sequence number if none provided + ctx, err = context.EnsureSequence(ctx) + if err != nil { + return err + } + res, err := ctx.SignBuildBroadcast(ctx.FromAddressName, msg, cdc) if err != nil { return err @@ -250,6 +279,6 @@ func GetPubKey(pubKeyStr string) (pk crypto.PubKey, err error) { } var pkEd crypto.PubKeyEd25519 copy(pkEd[:], pkBytes[:]) - pk = pkEd.Wrap() + pk = pkEd return } diff --git a/x/stake/test_common.go b/x/stake/test_common.go index 285364a5d..395a5bce0 100644 --- a/x/stake/test_common.go +++ b/x/stake/test_common.go @@ -8,7 +8,6 @@ import ( abci "github.com/tendermint/abci/types" crypto "github.com/tendermint/go-crypto" - oldwire "github.com/tendermint/go-wire" dbm "github.com/tendermint/tmlibs/db" "github.com/cosmos/cosmos-sdk/store" @@ -84,36 +83,22 @@ func subspace(prefix []byte) (start, end []byte) { return prefix, end } -// custom tx codec -// TODO: use new go-wire func makeTestCodec() *wire.Codec { + var cdc = wire.NewCodec() - const msgTypeSend = 0x1 - const msgTypeIssue = 0x2 - const msgTypeDeclareCandidacy = 0x3 - const msgTypeEditCandidacy = 0x4 - const msgTypeDelegate = 0x5 - const msgTypeUnbond = 0x6 - var _ = oldwire.RegisterInterface( - struct{ sdk.Msg }{}, - oldwire.ConcreteType{bank.SendMsg{}, msgTypeSend}, - oldwire.ConcreteType{bank.IssueMsg{}, msgTypeIssue}, - oldwire.ConcreteType{MsgDeclareCandidacy{}, msgTypeDeclareCandidacy}, - oldwire.ConcreteType{MsgEditCandidacy{}, msgTypeEditCandidacy}, - oldwire.ConcreteType{MsgDelegate{}, msgTypeDelegate}, - oldwire.ConcreteType{MsgUnbond{}, msgTypeUnbond}, - ) + // Register Msgs + cdc.RegisterInterface((*sdk.Msg)(nil), nil) + cdc.RegisterConcrete(bank.SendMsg{}, "test/stake/Send", nil) + cdc.RegisterConcrete(bank.IssueMsg{}, "test/stake/Issue", nil) + cdc.RegisterConcrete(MsgDeclareCandidacy{}, "test/stake/DeclareCandidacy", nil) + cdc.RegisterConcrete(MsgEditCandidacy{}, "test/stake/EditCandidacy", nil) + cdc.RegisterConcrete(MsgUnbond{}, "test/stake/Unbond", nil) - const accTypeApp = 0x1 - var _ = oldwire.RegisterInterface( - struct{ sdk.Account }{}, - oldwire.ConcreteType{&auth.BaseAccount{}, accTypeApp}, - ) - cdc := wire.NewCodec() + // Register AppAccount + cdc.RegisterInterface((*sdk.Account)(nil), nil) + cdc.RegisterConcrete(&auth.BaseAccount{}, "test/stake/Account", nil) + wire.RegisterCrypto(cdc) - // cdc.RegisterInterface((*sdk.Msg)(nil), nil) - // bank.RegisterWire(cdc) // Register bank.[SendMsg,IssueMsg] types. - // crypto.RegisterWire(cdc) // Register crypto.[PubKey,PrivKey,Signature] types. return cdc } @@ -141,10 +126,11 @@ func createTestInput(t *testing.T, isCheckTx bool, initCoins int64) (sdk.Context ctx := sdk.NewContext(ms, abci.Header{ChainID: "foochainid"}, isCheckTx, nil) cdc := makeTestCodec() - accountMapper := auth.NewAccountMapperSealed( + accountMapper := auth.NewAccountMapper( + cdc, // amino codec keyMain, // target store &auth.BaseAccount{}, // prototype - ) + ).Seal() ck := bank.NewCoinKeeper(accountMapper) keeper := NewKeeper(ctx, cdc, keyStake, ck) keeper.setPool(ctx, initialPool()) @@ -168,7 +154,7 @@ func newPubKey(pk string) (res crypto.PubKey) { //res, err = crypto.PubKeyFromBytes(pkBytes) var pkEd crypto.PubKeyEd25519 copy(pkEd[:], pkBytes[:]) - return pkEd.Wrap() + return pkEd } // for incode address generation