commit
07842b6876
|
@ -0,0 +1,5 @@
|
|||
Dockerfile
|
||||
Vagrantfile
|
||||
|
||||
build/
|
||||
coverage.txt
|
18
CHANGELOG.md
18
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
|
||||
|
|
46
Dockerfile
46
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"]
|
||||
|
|
|
@ -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
|
||||
|
|
15
Gopkg.toml
15
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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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()))
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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 <https://github.com/tendermint/go-wire>`__ and
|
||||
`data <https://github.com/tendermint/go-wire/tree/master/data>`__ to
|
||||
`go-amino <https://github.com/tendermint/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 ``<module name>/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:
|
||||
|
||||
|
|
|
@ -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 <https://github.com/tendermint/go-wire/tree/develop>`__.
|
||||
details, see the `go-amino documentation <https://github.com/tendermint/go-amino/tree/develop>`__.
|
||||
|
||||
|
||||
MultiStore
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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"}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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"}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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"`
|
||||
|
|
|
@ -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])
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
|
@ -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 {
|
||||
|
|
|
@ -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)}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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}}},
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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 = ""
|
||||
|
|
63
wire/wire.go
63
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
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
acc := accI.(struct{ sdk.Account }).Account
|
||||
return acc
|
||||
|
||||
/*
|
||||
accPtr := am.clonePrototypePtr()
|
||||
err := am.cdc.UnmarshalBinary(bz, accPtr)
|
||||
func (am accountMapper) decodeAccount(bz []byte) (acc sdk.Account) {
|
||||
err := am.cdc.UnmarshalBinaryBare(bz, &acc)
|
||||
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
|
||||
}
|
||||
|
|
|
@ -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() })
|
||||
}
|
||||
|
|
|
@ -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())))
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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"))
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue