Merge pull request #834 from cosmos/release/v0.15.0

Release/v0.15.0
This commit is contained in:
Ethan Buchman 2018-04-29 23:12:45 -04:00 committed by GitHub
commit 07842b6876
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
72 changed files with 1036 additions and 700 deletions

5
.dockerignore Normal file
View File

@ -0,0 +1,5 @@
Dockerfile
Vagrantfile
build/
coverage.txt

View File

@ -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

View File

@ -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"]

37
Gopkg.lock generated
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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
}

View File

@ -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
}

View File

@ -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()

View File

@ -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)
}
}
}

View File

@ -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))

12
client/lcd/wire.go Normal file
View File

@ -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)
}

View File

@ -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
}

View File

@ -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()))

View File

@ -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
}

12
client/rpc/wire.go Normal file
View File

@ -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)
}

View File

@ -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
}

View File

@ -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.

View File

@ -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(

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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"}

View File

@ -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
}

View File

@ -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)
}

View File

@ -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
}

View File

@ -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"}

View File

@ -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
}

View File

@ -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"`

View File

@ -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])

View File

@ -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 {

View File

@ -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)

View File

@ -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)

View File

@ -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
}

View File

@ -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,

View File

@ -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
}

12
server/wire.go Normal file
View File

@ -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)
}

View File

@ -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 {

View File

@ -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)}

View File

@ -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

View File

@ -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) {

View File

@ -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.

View File

@ -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)

View File

@ -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 {

View File

@ -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}}},
}

View File

@ -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

View File

@ -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))
}

View File

@ -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)

View File

@ -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
}

29
types/store_test.go Normal file
View File

@ -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)
}
}

View File

@ -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 = ""

View File

@ -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
}

View File

@ -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) {
}

View File

@ -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())
}

View File

@ -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)
}

View File

@ -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)

View File

@ -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
}

View File

@ -1,12 +1,9 @@
package auth
import (
"bytes"
"fmt"
"reflect"
oldwire "github.com/tendermint/go-wire"
sdk "github.com/cosmos/cosmos-sdk/types"
wire "github.com/cosmos/cosmos-sdk/wire"
)
@ -16,7 +13,7 @@ var _ sdk.AccountMapper = (*sealedAccountMapper)(nil)
// Implements sdk.AccountMapper.
// This AccountMapper encodes/decodes accounts using the
// go-wire (binary) encoding/decoding library.
// go-amino (binary) encoding/decoding library.
type accountMapper struct {
// The (unexposed) key used to access the store from the Context.
@ -30,9 +27,8 @@ type accountMapper struct {
}
// NewAccountMapper returns a new sdk.AccountMapper that
// uses go-wire to (binary) encode and decode concrete sdk.Accounts.
func NewAccountMapper(key sdk.StoreKey, proto sdk.Account) accountMapper {
cdc := wire.NewCodec()
// uses go-amino to (binary) encode and decode concrete sdk.Accounts.
func NewAccountMapper(cdc *wire.Codec, key sdk.StoreKey, proto sdk.Account) accountMapper {
return accountMapper{
key: key,
proto: proto,
@ -40,21 +36,7 @@ func NewAccountMapper(key sdk.StoreKey, proto sdk.Account) accountMapper {
}
}
// Create and return a sealed account mapper
func NewAccountMapperSealed(key sdk.StoreKey, proto sdk.Account) sealedAccountMapper {
cdc := wire.NewCodec()
am := accountMapper{
key: key,
proto: proto,
cdc: cdc,
}
RegisterWireBaseAccount(cdc)
// make accountMapper's WireCodec() inaccessible, return
return am.Seal()
}
// Returns the go-wire codec. You may need to register interfaces
// Returns the go-amino codec. You may need to register interfaces
// and concrete types here, if your app's sdk.Account
// implementation includes interface fields.
// NOTE: It is not secure to expose the codec, so check out
@ -103,7 +85,7 @@ type sealedAccountMapper struct {
}
// There's no way for external modules to mutate the
// sam.accountMapper.ctx from here, even with reflection.
// sam.accountMapper.cdc from here, even with reflection.
func (sam sealedAccountMapper) WireCodec() *wire.Codec {
panic("accountMapper is sealed")
}
@ -111,22 +93,6 @@ func (sam sealedAccountMapper) WireCodec() *wire.Codec {
//----------------------------------------
// misc.
// NOTE: currently unused
func (am accountMapper) clonePrototypePtr() interface{} {
protoRt := reflect.TypeOf(am.proto)
if protoRt.Kind() == reflect.Ptr {
protoErt := protoRt.Elem()
if protoErt.Kind() != reflect.Struct {
panic("accountMapper requires a struct proto sdk.Account, or a pointer to one")
}
protoRv := reflect.New(protoErt)
return protoRv.Interface()
} else {
protoRv := reflect.New(protoRt)
return protoRv.Interface()
}
}
// Creates a new struct (or pointer to struct) from am.proto.
func (am accountMapper) clonePrototype() sdk.Account {
protoRt := reflect.TypeOf(am.proto)
@ -152,34 +118,17 @@ func (am accountMapper) clonePrototype() sdk.Account {
}
func (am accountMapper) encodeAccount(acc sdk.Account) []byte {
bz, err := am.cdc.MarshalBinary(acc)
bz, err := am.cdc.MarshalBinaryBare(acc)
if err != nil {
panic(err)
}
return bz
}
func (am accountMapper) decodeAccount(bz []byte) sdk.Account {
// ... old go-wire ...
r, n, err := bytes.NewBuffer(bz), new(int), new(error)
accI := oldwire.ReadBinary(struct{ sdk.Account }{}, r, len(bz), n, err)
if *err != nil {
panic(*err)
func (am accountMapper) decodeAccount(bz []byte) (acc sdk.Account) {
err := am.cdc.UnmarshalBinaryBare(bz, &acc)
if err != nil {
panic(err)
}
acc := accI.(struct{ sdk.Account }).Account
return acc
/*
accPtr := am.clonePrototypePtr()
err := am.cdc.UnmarshalBinary(bz, accPtr)
if err != nil {
panic(err)
}
if reflect.ValueOf(am.proto).Kind() == reflect.Ptr {
return reflect.ValueOf(accPtr).Interface().(sdk.Account)
} else {
return reflect.ValueOf(accPtr).Elem().Interface().(sdk.Account)
}
*/
return
}

View File

@ -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() })
}

View File

@ -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())))

View File

@ -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
}

View File

@ -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 {

View File

@ -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)

View File

@ -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()))

View File

@ -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

View File

@ -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)

View File

@ -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"))

View File

@ -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")
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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