diff --git a/.gitignore b/.gitignore index 9b65c5c..c6fb54b 100644 --- a/.gitignore +++ b/.gitignore @@ -17,22 +17,13 @@ _cgo_defun.c _cgo_gotypes.go _cgo_export.* -_testmain.go - *.exe *.test *.prof .vscode/ -ledger/.project - .project -ledger/.settings/com.googlecode.goclipse.core.prefs - -build/ -testbed/testbed.go /vendor -data /.idea diff --git a/.travis.yml b/.travis.yml index f1a66cf..381fb2c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,8 @@ matrix: install: - export GOPATH=$HOME/gopath - export PATH=$HOME/gopath/bin:$PATH - - curl https://glide.sh/get | sh + - mkdir -p $GOPATH/bin + - wget https://github.com/golang/dep/releases/download/v0.4.1/dep-linux-amd64 -O $GOPATH/bin/dep && chmod +x $GOPATH/bin/dep script: - export GOPATH=$HOME/gopath diff --git a/Gopkg.lock b/Gopkg.lock new file mode 100644 index 0000000..634f6a0 --- /dev/null +++ b/Gopkg.lock @@ -0,0 +1,491 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + name = "github.com/bgentry/speakeasy" + packages = ["."] + revision = "4aabc24848ce5fd31929f7d1e4ea74d3709c14cd" + version = "v0.1.0" + +[[projects]] + branch = "master" + name = "github.com/btcsuite/btcd" + packages = ["btcec"] + revision = "2be2f12b358dc57d70b8f501b00be450192efbc3" + +[[projects]] + name = "github.com/cosmos/cosmos-sdk" + packages = [ + "baseapp", + "client", + "client/builder", + "client/keys", + "client/lcd", + "client/rpc", + "client/tx", + "mock", + "server", + "store", + "types", + "version", + "wire", + "x/auth", + "x/auth/commands", + "x/auth/rest", + "x/bank", + "x/bank/commands", + "x/bank/rest", + "x/ibc", + "x/ibc/rest" + ] + revision = "4f0acc4df8de03ac5b90b2173e5c1f73afb0c04e" + version = "v0.13.1" + +[[projects]] + name = "github.com/davecgh/go-spew" + packages = ["spew"] + revision = "346938d642f2ec3594ed81d874461961cd0faa76" + version = "v1.1.0" + +[[projects]] + branch = "master" + name = "github.com/ebuchman/fail-test" + packages = ["."] + revision = "95f809107225be108efcf10a3509e4ea6ceef3c4" + +[[projects]] + name = "github.com/fsnotify/fsnotify" + packages = ["."] + revision = "c2828203cd70a50dcccfb2761f8b1f8ceef9a8e9" + version = "v1.4.7" + +[[projects]] + name = "github.com/go-kit/kit" + packages = [ + "log", + "log/level", + "log/term" + ] + revision = "4dc7be5d2d12881735283bcab7352178e190fc71" + version = "v0.6.0" + +[[projects]] + name = "github.com/go-logfmt/logfmt" + packages = ["."] + revision = "390ab7935ee28ec6b286364bba9b4dd6410cb3d5" + version = "v0.3.0" + +[[projects]] + name = "github.com/go-stack/stack" + packages = ["."] + revision = "259ab82a6cad3992b4e21ff5cac294ccb06474bc" + version = "v1.7.0" + +[[projects]] + name = "github.com/gogo/protobuf" + packages = [ + "gogoproto", + "jsonpb", + "proto", + "protoc-gen-gogo/descriptor", + "sortkeys", + "types" + ] + revision = "1adfc126b41513cc696b209667c8656ea7aac67c" + version = "v1.0.0" + +[[projects]] + name = "github.com/golang/protobuf" + packages = [ + "proto", + "ptypes", + "ptypes/any", + "ptypes/duration", + "ptypes/timestamp" + ] + revision = "925541529c1fa6821df4e44ce2723319eb2be768" + version = "v1.0.0" + +[[projects]] + branch = "master" + name = "github.com/golang/snappy" + packages = ["."] + revision = "553a641470496b2327abcac10b36396bd98e45c9" + +[[projects]] + name = "github.com/gorilla/context" + packages = ["."] + revision = "1ea25387ff6f684839d82767c1733ff4d4d15d0a" + version = "v1.1" + +[[projects]] + name = "github.com/gorilla/mux" + packages = ["."] + revision = "53c1911da2b537f792e7cafcb446b05ffe33b996" + version = "v1.6.1" + +[[projects]] + name = "github.com/gorilla/websocket" + packages = ["."] + revision = "ea4d1f681babbce9545c9c5f3d5194a789c89f5b" + version = "v1.2.0" + +[[projects]] + branch = "master" + name = "github.com/hashicorp/hcl" + packages = [ + ".", + "hcl/ast", + "hcl/parser", + "hcl/printer", + "hcl/scanner", + "hcl/strconv", + "hcl/token", + "json/parser", + "json/scanner", + "json/token" + ] + revision = "f40e974e75af4e271d97ce0fc917af5898ae7bda" + +[[projects]] + branch = "master" + name = "github.com/howeyc/crc16" + packages = ["."] + revision = "2b2a61e366a66d3efb279e46176e7291001e0354" + +[[projects]] + name = "github.com/inconshreveable/mousetrap" + packages = ["."] + revision = "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75" + version = "v1.0" + +[[projects]] + branch = "master" + name = "github.com/jmhodges/levigo" + packages = ["."] + revision = "c42d9e0ca023e2198120196f842701bb4c55d7b9" + +[[projects]] + branch = "master" + name = "github.com/kr/logfmt" + packages = ["."] + revision = "b84e30acd515aadc4b783ad4ff83aff3299bdfe0" + +[[projects]] + name = "github.com/magiconair/properties" + packages = ["."] + revision = "c3beff4c2358b44d0493c7dda585e7db7ff28ae6" + version = "v1.7.6" + +[[projects]] + name = "github.com/mattn/go-isatty" + packages = ["."] + revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39" + version = "v0.0.3" + +[[projects]] + branch = "master" + name = "github.com/mitchellh/mapstructure" + packages = ["."] + revision = "00c29f56e2386353d58c599509e8dc3801b0d716" + +[[projects]] + name = "github.com/pelletier/go-toml" + packages = ["."] + revision = "acdc4509485b587f5e675510c4f2c63e90ff68a8" + version = "v1.1.0" + +[[projects]] + name = "github.com/pkg/errors" + packages = ["."] + revision = "645ef00459ed84a119197bfb8d8205042c6df63d" + version = "v0.8.0" + +[[projects]] + name = "github.com/pmezard/go-difflib" + packages = ["difflib"] + revision = "792786c7400a136282c1664665ae0a8db921c6c2" + version = "v1.0.0" + +[[projects]] + branch = "master" + name = "github.com/rcrowley/go-metrics" + packages = ["."] + revision = "8732c616f52954686704c8645fe1a9d59e9df7c1" + +[[projects]] + name = "github.com/spf13/afero" + packages = [ + ".", + "mem" + ] + revision = "bb8f1927f2a9d3ab41c9340aa034f6b803f4359c" + version = "v1.0.2" + +[[projects]] + name = "github.com/spf13/cast" + packages = ["."] + revision = "8965335b8c7107321228e3e3702cab9832751bac" + version = "v1.2.0" + +[[projects]] + name = "github.com/spf13/cobra" + packages = ["."] + revision = "a1f051bc3eba734da4772d60e2d677f47cf93ef4" + version = "v0.0.2" + +[[projects]] + branch = "master" + name = "github.com/spf13/jwalterweatherman" + packages = ["."] + revision = "7c0cea34c8ece3fbeb2b27ab9b59511d360fb394" + +[[projects]] + name = "github.com/spf13/pflag" + packages = ["."] + revision = "e57e3eeb33f795204c1ca35f56c44f83227c6e66" + version = "v1.0.0" + +[[projects]] + name = "github.com/spf13/viper" + packages = ["."] + revision = "b5e8006cbee93ec955a89ab31e0e3ce3204f3736" + version = "v1.0.2" + +[[projects]] + name = "github.com/stretchr/testify" + packages = [ + "assert", + "require" + ] + revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71" + version = "v1.2.1" + +[[projects]] + branch = "master" + name = "github.com/syndtr/goleveldb" + packages = [ + "leveldb", + "leveldb/cache", + "leveldb/comparer", + "leveldb/errors", + "leveldb/filter", + "leveldb/iterator", + "leveldb/journal", + "leveldb/memdb", + "leveldb/opt", + "leveldb/storage", + "leveldb/table", + "leveldb/util" + ] + revision = "714f901b98fdb3aa954b4193d8cbd64a28d80cad" + +[[projects]] + name = "github.com/tendermint/abci" + packages = [ + "client", + "example/code", + "example/kvstore", + "server", + "types" + ] + revision = "46686763ba8ea595ede16530ed4a40fb38f49f94" + version = "v0.10.2" + +[[projects]] + branch = "master" + name = "github.com/tendermint/ed25519" + packages = [ + ".", + "edwards25519", + "extra25519" + ] + revision = "d8387025d2b9d158cf4efb07e7ebf814bcce2057" + +[[projects]] + name = "github.com/tendermint/go-crypto" + packages = [ + ".", + "keys", + "keys/bcrypt", + "keys/words", + "keys/words/wordlist" + ] + revision = "c3e19f3ea26f5c3357e0bcbb799b0761ef923755" + version = "v0.5.0" + +[[projects]] + name = "github.com/tendermint/go-wire" + packages = [ + ".", + "data" + ] + revision = "fa721242b042ecd4c6ed1a934ee740db4f74e45c" + source = "github.com/tendermint/go-amino" + version = "v0.7.3" + +[[projects]] + name = "github.com/tendermint/iavl" + packages = ["."] + revision = "fd37a0fa3a7454423233bc3d5ea828f38e0af787" + version = "v0.7.0" + +[[projects]] + name = "github.com/tendermint/tendermint" + packages = [ + "blockchain", + "cmd/tendermint/commands", + "config", + "consensus", + "consensus/types", + "evidence", + "lite", + "lite/client", + "lite/errors", + "lite/files", + "lite/proxy", + "mempool", + "node", + "p2p", + "p2p/conn", + "p2p/pex", + "p2p/trust", + "p2p/upnp", + "proxy", + "rpc/client", + "rpc/core", + "rpc/core/types", + "rpc/grpc", + "rpc/lib", + "rpc/lib/client", + "rpc/lib/server", + "rpc/lib/types", + "state", + "state/txindex", + "state/txindex/kv", + "state/txindex/null", + "types", + "types/priv_validator", + "version", + "wire" + ] + revision = "6f9956990c444d53f62f2a3905ed410cfe9afe77" + version = "v0.17.1" + +[[projects]] + name = "github.com/tendermint/tmlibs" + packages = [ + "autofile", + "cli", + "cli/flags", + "clist", + "common", + "db", + "flowrate", + "log", + "merkle", + "pubsub", + "pubsub/query" + ] + revision = "24da7009c3d8c019b40ba4287495749e3160caca" + version = "v0.7.1" + +[[projects]] + branch = "master" + name = "golang.org/x/crypto" + packages = [ + "blowfish", + "curve25519", + "nacl/box", + "nacl/secretbox", + "openpgp/armor", + "openpgp/errors", + "poly1305", + "ripemd160", + "salsa20/salsa" + ] + revision = "12892e8c234f4fe6f6803f052061de9057903bb2" + +[[projects]] + branch = "master" + name = "golang.org/x/net" + packages = [ + "context", + "http2", + "http2/hpack", + "idna", + "internal/timeseries", + "lex/httplex", + "trace" + ] + revision = "b68f30494add4df6bd8ef5e82803f308e7f7c59c" + +[[projects]] + branch = "master" + name = "golang.org/x/sys" + packages = ["unix"] + revision = "378d26f46672a356c46195c28f61bdb4c0a781dd" + +[[projects]] + name = "golang.org/x/text" + packages = [ + "collate", + "collate/build", + "internal/colltab", + "internal/gen", + "internal/tag", + "internal/triegen", + "internal/ucd", + "language", + "secure/bidirule", + "transform", + "unicode/bidi", + "unicode/cldr", + "unicode/norm", + "unicode/rangetable" + ] + revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0" + version = "v0.3.0" + +[[projects]] + branch = "master" + name = "google.golang.org/genproto" + packages = ["googleapis/rpc/status"] + revision = "ab0870e398d5dd054b868c0db1481ab029b9a9f2" + +[[projects]] + name = "google.golang.org/grpc" + packages = [ + ".", + "balancer", + "codes", + "connectivity", + "credentials", + "grpclb/grpc_lb_v1/messages", + "grpclog", + "internal", + "keepalive", + "metadata", + "naming", + "peer", + "resolver", + "stats", + "status", + "tap", + "transport" + ] + revision = "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" + version = "v1.7.5" + +[[projects]] + name = "gopkg.in/yaml.v2" + packages = ["."] + revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183" + version = "v2.2.1" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "ea35f0b16bef29139eefd53b530a852b1d8e0d6f84b3111ec6fca26761a282aa" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml new file mode 100644 index 0000000..2935505 --- /dev/null +++ b/Gopkg.toml @@ -0,0 +1,59 @@ +# Gopkg.toml example +# +# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md +# for detailed Gopkg.toml documentation. +# +# required = ["github.com/user/thing/cmd/thing"] +# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] +# +# [[constraint]] +# name = "github.com/user/project" +# version = "1.0.0" +# +# [[constraint]] +# name = "github.com/user/project2" +# branch = "dev" +# source = "github.com/myfork/project2" +# +# [[override]] +# name = "github.com/x/y" +# version = "2.4.0" +# +# [prune] +# non-go = false +# go-tests = true +# unused-packages = true + + +[[constraint]] + name = "github.com/cosmos/cosmos-sdk" + version = "~0.13.1" + +[[constraint]] + name = "github.com/spf13/cobra" + version = "~0.0.2" + +[[constraint]] + name = "github.com/stretchr/testify" + version = "~1.2.1" + +[[constraint]] + name = "github.com/tendermint/abci" + version = "~0.10.2" + +[[constraint]] + name = "github.com/tendermint/go-crypto" + version = "~0.5.0" + +[[constraint]] + name = "github.com/tendermint/go-wire" + source = "github.com/tendermint/go-amino" + version = "~0.7.3" + +[[constraint]] + name = "github.com/tendermint/tmlibs" + version = "~0.7.1" + +[prune] + go-tests = true + unused-packages = true diff --git a/Makefile b/Makefile index 42aeaa8..875bdf0 100644 --- a/Makefile +++ b/Makefile @@ -1,24 +1,30 @@ PACKAGES=$(shell go list ./... | grep -v '/vendor/') BUILD_FLAGS = -ldflags "-X github.com/tendermint/clearchain.Version=`git describe`" +TARGETS = clearchainctl clearchaind -all: get_vendor_deps build test +all: dist-clean get_vendor_deps build test ######################################## ### Build -build: clearchaind +build: $(TARGETS) clearchaind: go build $(BUILD_FLAGS) ./cmd/clearchaind +clearchainctl: + go build $(BUILD_FLAGS) ./cmd/clearchainctl ######################################## ### Tools & dependencies get_vendor_deps: - @rm -rf vendor/ - @echo "--> Running glide install" - @glide install + dep ensure -v + +dep: $(GOPATH)/bin/dep +$(GOPATH)/bin/dep: + mkdir -p $(GOPATH)/bin + wget https://github.com/golang/dep/releases/download/v0.4.1/dep-linux-amd64 -O $@ && chmod +x $@ ######################################## @@ -34,9 +40,20 @@ coverage.txt: clean ( cat profile.out >> $@ ; rm profile.out ) \ done -clean: + +dist-clean: clean clean-vendor +clean: clean-arch clean-noarch + +clean-arch: + rm -f $(TARGETS) + +clean-noarch: rm -f profile.out coverage.txt +clean-vendor: + @echo "--> Purge vendor/ directory" + rm -rf vendor/ + benchmark: @go test -bench=. $(PACKAGES) @@ -44,4 +61,4 @@ benchmark: # To avoid unintended conflicts with file names, always add to .PHONY # unless there is a reason not to. # https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html -.PHONY: build check_tools get_vendor_deps test benchmark clean +.PHONY: build dep get_vendor_deps test benchmark clean clean-arch clean-noarch clean-vendor dist-clean diff --git a/app/app.go b/app/app.go index fce6e23..23c23e8 100644 --- a/app/app.go +++ b/app/app.go @@ -6,11 +6,11 @@ import ( "github.com/cosmos/cosmos-sdk/baseapp" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/tendermint/abci/server" abci "github.com/tendermint/abci/types" "github.com/tendermint/clearchain/types" - wire "github.com/tendermint/go-wire" cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" @@ -77,9 +77,12 @@ func (app *ClearchainApp) RunForever(addrPtr string) { func (app *ClearchainApp) txDecoder(txBytes []byte) (sdk.Tx, sdk.Error) { // StdTx.Msg is an interface. The concrete types are registered by MakeCodec. var tx = sdk.StdTx{} + if len(txBytes) == 0 { + return nil, sdk.ErrTxDecode("txBytes are empty") + } err := app.cdc.UnmarshalBinary(txBytes, &tx) if err != nil { - return nil, sdk.ErrTxParse("").TraceCause(err, "") + return nil, sdk.ErrTxDecode("").TraceCause(err, "") } return tx, nil } diff --git a/app/app_test.go b/app/app_test.go index 2e16d61..97233ba 100644 --- a/app/app_test.go +++ b/app/app_test.go @@ -1,6 +1,7 @@ package app import ( + "bytes" "encoding/hex" "os" "path/filepath" @@ -9,6 +10,7 @@ import ( "github.com/stretchr/testify/assert" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" abci "github.com/tendermint/abci/types" crypto "github.com/tendermint/go-crypto" @@ -24,18 +26,18 @@ func TestApp_DepositMsg(t *testing.T) { cc := newTestClearchainApp() junk := []byte("khekfhewgfsug") - cc.BeginBlock(abci.RequestBeginBlock{}) // send a deposit msg - chOpAddr, chOpPrivKey := fakeOpAccount(cc, types.EntityClearingHouse, "CH") - custAssetAddr := fakeAssetAccount(cc, nil, types.EntityCustodian, "CUST") - memberAssetAddr := fakeAssetAccount(cc, nil, types.EntityIndividualClearingMember, "ICM") + // garbage in, garbage out + ctx := cc.NewContext(false, abci.Header{}) + chOpAddr, chOpPrivKey := fakeOpAccount(cc, ctx, types.EntityClearingHouse, "CH") + custAssetAddr := fakeAssetAccount(cc, ctx, sdk.Coins{}, types.EntityCustodian, "CUST") + memberAssetAddr := fakeAssetAccount(cc, ctx, sdk.Coins{}, types.EntityIndividualClearingMember, "ICM") depositMsg := types.DepositMsg{Operator: chOpAddr, Sender: custAssetAddr, Recipient: memberAssetAddr, Amount: sdk.Coin{"USD", 700}} - depositTx := makeTx(depositMsg, chOpPrivKey) - // garbage in, garbage out + depositTx := makeTx(cc.cdc, depositMsg, chOpPrivKey) dres := cc.DeliverTx(junk) - assert.EqualValues(t, sdk.CodeTxParse, dres.Code, dres.Log) + assert.EqualValues(t, sdk.CodeTxDecode, dres.Code, dres.Log) // get real working dres = cc.DeliverTx(depositTx) assert.EqualValues(t, sdk.CodeOK, dres.Code, dres.Log) @@ -44,8 +46,8 @@ func TestApp_DepositMsg(t *testing.T) { // Query data to verify the deposit res := cc.Query(abci.RequestQuery{Data: memberAssetAddr, Path: "/main/key"}) - codec := types.MakeCodec() - var foundAcc types.AppAccount + codec := cc.cdc + var foundAcc *types.AppAccount err := codec.UnmarshalBinary(res.GetValue(), &foundAcc) assert.Nil(t, err) assert.NotNil(t, foundAcc) @@ -57,17 +59,18 @@ func TestApp_FreezeOperator(t *testing.T) { cc.BeginBlock(abci.RequestBeginBlock{}) // send a deposit msg - chAdmAddr, chAdmPrivKey := fakeAdminAccount(cc, types.EntityClearingHouse, "CH") - chOpAddr, chOpPrivKey := fakeOpAccount(cc, types.EntityClearingHouse, "CH") - custAssetAddr := fakeAssetAccount(cc, nil, types.EntityCustodian, "CUST") - memberAssetAddr := fakeAssetAccount(cc, nil, types.EntityIndividualClearingMember, "ICM") + ctx := cc.NewContext(false, abci.Header{}) + chAdmAddr, chAdmPrivKey := fakeAdminAccount(cc, ctx, types.EntityClearingHouse, "CH") + chOpAddr, chOpPrivKey := fakeOpAccount(cc, ctx, types.EntityClearingHouse, "CH") + custAssetAddr := fakeAssetAccount(cc, ctx, sdk.Coins{}, types.EntityCustodian, "CUST") + memberAssetAddr := fakeAssetAccount(cc, ctx, sdk.Coins{}, types.EntityIndividualClearingMember, "ICM") depositMsg := types.DepositMsg{Operator: chOpAddr, Sender: custAssetAddr, Recipient: memberAssetAddr, Amount: sdk.Coin{"USD", 700}} freezeOpMsg := types.FreezeOperatorMsg{types.BaseFreezeAccountMsg{Admin: chAdmAddr, Target: chOpAddr}} - freezeOperatorTx := makeTx(freezeOpMsg, chAdmPrivKey) + freezeOperatorTx := makeTx(cc.cdc, freezeOpMsg, chAdmPrivKey) dres := cc.DeliverTx(freezeOperatorTx) assert.EqualValues(t, sdk.CodeOK, dres.Code, dres.Log) - depositTx := makeTx(depositMsg, chOpPrivKey) + depositTx := makeTx(cc.cdc, depositMsg, chOpPrivKey) // get real working dres = cc.DeliverTx(depositTx) assert.EqualValues(t, types.CodeInactiveAccount, dres.Code, dres.Log) @@ -79,17 +82,18 @@ func TestApp_FreezeAdmin(t *testing.T) { cc.BeginBlock(abci.RequestBeginBlock{}) // send a deposit msg - chAdmAddr, chAdmPrivKey := fakeAdminAccount(cc, types.EntityClearingHouse, "CH") - memAdmAddr, memAdmPrivKey := fakeAdminAccount(cc, types.EntityGeneralClearingMember, "GCM") - memOpAddr, _ := fakeOpAccount(cc, types.EntityGeneralClearingMember, "GCM") + ctx := cc.NewContext(false, abci.Header{}) + chAdmAddr, chAdmPrivKey := fakeAdminAccount(cc, ctx, types.EntityClearingHouse, "CH") + memAdmAddr, memAdmPrivKey := fakeAdminAccount(cc, ctx, types.EntityGeneralClearingMember, "GCM") + memOpAddr, _ := fakeOpAccount(cc, ctx, types.EntityGeneralClearingMember, "GCM") // the CH admin freezes the member admin freezeAdmMsg := types.FreezeAdminMsg{types.BaseFreezeAccountMsg{Admin: chAdmAddr, Target: memAdmAddr}} - freezeAdmTx := makeTx(freezeAdmMsg, chAdmPrivKey) + freezeAdmTx := makeTx(cc.cdc, freezeAdmMsg, chAdmPrivKey) dres := cc.DeliverTx(freezeAdmTx) assert.EqualValues(t, sdk.CodeOK, dres.Code, dres.Log) // the member's admin can no longer freeze its own operators freezeOpMsg := types.FreezeOperatorMsg{types.BaseFreezeAccountMsg{Admin: memAdmAddr, Target: memOpAddr}} - freezeOperatorTx := makeTx(freezeOpMsg, memAdmPrivKey) + freezeOperatorTx := makeTx(cc.cdc, freezeOpMsg, memAdmPrivKey) dres = cc.DeliverTx(freezeOperatorTx) assert.EqualValues(t, types.CodeInactiveAccount, dres.Code, dres.Log) cc.EndBlock(abci.RequestEndBlock{}) @@ -99,31 +103,36 @@ func TestApp_FreezeAdmin(t *testing.T) { // It makes the app read an external genesis file and then verifies that all accounts were created by using the Query interface func Test_Genesis(t *testing.T) { - codec := types.MakeCodec() app := newTestClearchainApp() - absPathFileOk, _ := filepath.Abs("test/genesis_ok_ch_admin_test.json") - pubBytes, _ := hex.DecodeString("328eaf59335aa6724f253ca8f1620b249bb83e665d7e5134e9bf92079b2549df3572f874") + codec := app.cdc + absPathFileOk, err := filepath.Abs("test/genesis_ok_ch_admin_test.json") + pubBytes, _ := hex.DecodeString("01328eaf59335aa6724f253ca8f1620b249bb83e665d7e5134e9bf92079b2549df3572f874") publicKey1, _ := crypto.PubKeyFromBytes(pubBytes) adminCreated1 := types.NewAdminUser(publicKey1, nil, "ClearChain", "ch") stateBytes, _ := common.ReadFile(absPathFileOk) vals := []abci.Validator{} + res := app.Query(abci.RequestQuery{Data: []byte("nothing"), Path: "/main/key"}) + assert.Equal(t, 0, len(res.Value)) app.BeginBlock(abci.RequestBeginBlock{}) - app.InitChain(abci.RequestInitChain{vals, stateBytes}) + app.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes}) app.Commit() app.EndBlock(abci.RequestEndBlock{}) expAcc := adminCreated1 // Query the existing data - res := app.Query(abci.RequestQuery{Data: expAcc.GetAddress(), Path: "/main/key"}) + res = app.Query(abci.RequestQuery{Data: expAcc.GetAddress().Bytes(), Path: "/main/key"}) assert.NotNil(t, res.GetValue()) - var foundAcc types.AppAccount - err := codec.UnmarshalBinary(res.GetValue(), &foundAcc) + var foundAcc *types.AppAccount + err = codec.UnmarshalBinary(res.Value, &foundAcc) + if err != nil { + panic(err) + } assert.Nil(t, err) - assert.Equal(t, hex.EncodeToString(expAcc.Address), hex.EncodeToString(foundAcc.Address)) + assert.True(t, bytes.Equal(expAcc.Address.Bytes(), foundAcc.Address.Bytes())) assert.True(t, expAcc.PubKey.Equals(foundAcc.PubKey)) assert.True(t, foundAcc.Coins.IsZero()) - assert.True(t, foundAcc.Creator == nil) + assert.Equal(t, len(foundAcc.Creator), 0) assert.Equal(t, expAcc.EntityName, foundAcc.EntityName) assert.Equal(t, expAcc.EntityType, foundAcc.EntityType) assert.Equal(t, expAcc.AccountType, foundAcc.AccountType) @@ -134,21 +143,19 @@ func Test_Genesis(t *testing.T) { assert.True(t, foundAcc.Admin) } -func makeTx(msg sdk.Msg, keys ...crypto.PrivKey) []byte { - tx := sdk.StdTx{Msg: msg} - +func makeTx(cdc *wire.Codec, msg sdk.Msg, keys ...crypto.PrivKey) []byte { sigs := make([]sdk.StdSignature, len(keys)) for i, k := range keys { + sig := k.Sign(sdk.StdSignBytes("", []int64{0}, sdk.StdFee{}, msg)) sigs[i] = sdk.StdSignature{ PubKey: k.PubKey(), + Signature: sig, Sequence: 0, - Signature: k.Sign(tx.GetSignBytes()), } } - tx.Signatures = sigs + tx := sdk.NewStdTx(msg, sdk.StdFee{}, sigs) - cc := types.MakeCodec() - bz, err := cc.MarshalBinary(tx) + bz, err := cdc.MarshalBinary(tx) if err != nil { panic(err) } @@ -156,33 +163,30 @@ func makeTx(msg sdk.Msg, keys ...crypto.PrivKey) []byte { return bz } -func fakeAssetAccount(cc *ClearchainApp, cash sdk.Coins, typ string, entityName string) crypto.Address { +func fakeAssetAccount(cc *ClearchainApp, ctx sdk.Context, cash sdk.Coins, typ string, entityName string) sdk.Address { pub := crypto.GenPrivKeyEd25519().PubKey() addr := pub.Address() acct := types.NewAssetAccount(pub, cash, nil, entityName, typ) - var ctx = cc.NewContext(false, abci.Header{}) cc.accountMapper.SetAccount(ctx, acct) return addr } -func fakeOpAccount(cc *ClearchainApp, typ string, entityName string) (crypto.Address, crypto.PrivKey) { +func fakeOpAccount(cc *ClearchainApp, ctx sdk.Context, typ string, entityName string) (sdk.Address, crypto.PrivKey) { priv := crypto.GenPrivKeyEd25519() pub := priv.PubKey() addr := pub.Address() - acct := types.NewOpUser(pub, nil, entityName, typ) - var ctx = cc.NewContext(false, abci.Header{}) + acct := types.NewOpUser(pub, []byte(""), entityName, typ) cc.accountMapper.SetAccount(ctx, acct) - return addr, priv + return addr, priv.Wrap() } -func fakeAdminAccount(cc *ClearchainApp, typ string, entityName string) (crypto.Address, crypto.PrivKey) { +func fakeAdminAccount(cc *ClearchainApp, ctx sdk.Context, typ string, entityName string) (sdk.Address, crypto.PrivKey) { priv := crypto.GenPrivKeyEd25519() pub := priv.PubKey() addr := pub.Address() - acct := types.NewAdminUser(pub, nil, entityName, typ) - var ctx = cc.NewContext(false, abci.Header{}) + acct := types.NewAdminUser(pub, []byte(""), entityName, typ) cc.accountMapper.SetAccount(ctx, acct) - return addr, priv + return addr, priv.Wrap() } // newTestClearchainApp a ClearchainApp with an in-memory datastore diff --git a/app/test/genesis_ok_ch_admin_test.json b/app/test/genesis_ok_ch_admin_test.json index e7f689e..06fdd22 100644 --- a/app/test/genesis_ok_ch_admin_test.json +++ b/app/test/genesis_ok_ch_admin_test.json @@ -1,7 +1,7 @@ -{ +{ "ch_admin": - { - "public_key":"328eaf59335aa6724f253ca8f1620b249bb83e665d7e5134e9bf92079b2549df3572f874", - "entity_name":"ClearChain" - } -} \ No newline at end of file + { + "public_key":"01328eaf59335aa6724f253ca8f1620b249bb83e665d7e5134e9bf92079b2549df3572f874", + "entity_name":"ClearChain" + } +} diff --git a/circle.yml b/circle.yml index 912d3b7..936d2d1 100644 --- a/circle.yml +++ b/circle.yml @@ -11,7 +11,7 @@ machine: dependencies: pre: - mkdir -p $GOPATH/bin - - curl https://glide.sh/get | sh + - wget https://github.com/golang/dep/releases/download/v0.4.1/dep-linux-amd64 -O $GOPATH/bin/dep && chmod +x $GOPATH/bin/dep override: - go version - mkdir -p "$PROJECT_PARENT_PATH" diff --git a/cmd/clearchainctl/main.go b/cmd/clearchainctl/main.go new file mode 100644 index 0000000..18396be --- /dev/null +++ b/cmd/clearchainctl/main.go @@ -0,0 +1,63 @@ +package main + +import ( + "os" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/keys" + "github.com/cosmos/cosmos-sdk/client/lcd" + "github.com/cosmos/cosmos-sdk/client/rpc" + "github.com/cosmos/cosmos-sdk/client/tx" + authcmd "github.com/cosmos/cosmos-sdk/x/auth/commands" + "github.com/spf13/cobra" + "github.com/tendermint/clearchain/commands" + "github.com/tendermint/clearchain/types" + "github.com/tendermint/tmlibs/cli" +) + +const ( + defaultConfigBaseDir = ".clearchainctl" +) + +var ( + clearchainctlCmd = &cobra.Command{ + Use: "clearchainctl", + Short: "Clearchain light-client", + } +) + +func main() { + cobra.EnableCommandSorting = false + cdc := types.MakeCodec() + rpc.AddCommands(clearchainctlCmd) + clearchainctlCmd.AddCommand(client.LineBreak) + tx.AddCommands(clearchainctlCmd, cdc) + clearchainctlCmd.AddCommand(client.LineBreak) + + // add clearchain-specific commands + clearchainctlCmd.AddCommand( + client.GetCommands( + authcmd.GetAccountCmd("main", cdc, types.GetAccountDecoder(cdc)), + )...) + clearchainctlCmd.AddCommand( + client.PostCommands( + commands.GetCreateAdminTxCmd(cdc), + commands.GetCreateOperatorTxCmd(cdc), + commands.GetCreateAssetAccountTxCmd(cdc), + )...) + clearchainctlCmd.AddCommand(commands.GetExportPubCmd(cdc)) + //clearchainctlCmd.AddCommand(commands.GetImportPubCmd(cdc)) + + // add proxy, version and key info + clearchainctlCmd.AddCommand( + client.LineBreak, + lcd.ServeCommand(cdc), + keys.Commands(), + client.LineBreak, + commands.VersionCmd, + ) + + // prepare and add flags + executor := cli.PrepareMainCmd(clearchainctlCmd, "CC", os.ExpandEnv(defaultConfigBaseDir)) + executor.Execute() +} diff --git a/cmd/clearchaind/main.go b/cmd/clearchaind/main.go index af74994..11cc04e 100644 --- a/cmd/clearchaind/main.go +++ b/cmd/clearchaind/main.go @@ -6,21 +6,27 @@ import ( "fmt" "os" + "github.com/spf13/viper" + "github.com/cosmos/cosmos-sdk/server" "github.com/spf13/cobra" abci "github.com/tendermint/abci/types" "github.com/tendermint/clearchain" "github.com/tendermint/clearchain/app" + "github.com/tendermint/clearchain/types" crypto "github.com/tendermint/go-crypto" "github.com/tendermint/go-crypto/keys" "github.com/tendermint/go-crypto/keys/words" "github.com/tendermint/tmlibs/cli" + cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" ) const ( - defaultConfigBaseDir = "$HOME/.clearchaind" + defaultClearingHouseName = "ClearingHouse" + defaultConfigBaseDir = ".clearchaind" + flagClearingHouseName = "clearing-house-name" ) var ( @@ -45,12 +51,24 @@ func doVersionCmd(cmd *cobra.Command, args []string) { fmt.Fprintln(os.Stderr, v) } +func initCommand(logger log.Logger) *cobra.Command { + cmd := server.InitCmd(defaultOptions, logger) + cmd.Flags().String(flagClearingHouseName, defaultClearingHouseName, "Clearing House name") + cmd.Args = cobra.MaximumNArgs(1) + return cmd +} + func main() { logger := log.NewTMLogger(log.NewSyncWriter(os.Stderr)).With("module", "main") + initCmd := server.InitCmd(defaultOptions, logger) + initCmd.Flags().String(flagClearingHouseName, defaultClearingHouseName, "Clearing House name") + initCmd.Args = cobra.MaximumNArgs(1) clearchaindCmd.AddCommand( - server.InitCmd(defaultOptions, logger), + initCommand(logger), server.StartCmd(generateApp, logger), server.UnsafeResetAllCmd(logger), + server.ShowNodeIdCmd(logger), + server.ShowValidatorCmd(logger), versionCmd, ) // prepare and add flags @@ -59,22 +77,31 @@ func main() { executor.Execute() } +func readOrGenerateKey(args []string) (crypto.PubKey, string, error) { + if len(args) != 0 { // user has given a hexadecimal pubkey on the command line + pub, err := types.PubKeyFromHexString(args[0]) + if err != nil { + return crypto.PubKey{}, "", err + } + return pub, "", nil + } + return generateKey() +} + // defaultOptions sets up the app_options for the // default genesis file -func defaultOptions(args []string) (json.RawMessage, error) { - pub, secret, err := generateKey() +func defaultOptions(args []string) (json.RawMessage, string, cmn.HexBytes, error) { + pub, secret, err := readOrGenerateKey(args) if err != nil { - return nil, err + return nil, "", nil, err } - fmt.Println("Secret phrase to access coins:") - fmt.Println(secret) opts := fmt.Sprintf(`{ "ch_admin": { "public_key": "%s", - "entity_name": "Clearchain" + "entity_name": "%s" } - }`, hex.EncodeToString(pub.Bytes())) - return json.RawMessage(opts), nil + }`, hex.EncodeToString(pub.Bytes()), viper.GetString(flagClearingHouseName)) + return json.RawMessage(opts), secret, pub.Address(), nil } func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { @@ -90,7 +117,7 @@ func generateKey() (crypto.PubKey, string, error) { // construct an in-memory key store codec, err := words.LoadCodec("english") if err != nil { - return nil, "", err + return crypto.PubKey{}, "", err } keybase := keys.New( dbm.NewMemDB(), @@ -100,7 +127,7 @@ func generateKey() (crypto.PubKey, string, error) { // generate a private key, with recovery phrase info, secret, err := keybase.Create("name", "pass", keys.AlgoEd25519) if err != nil { - return nil, "", err + return crypto.PubKey{}, "", err } return info.PubKey, secret, nil diff --git a/commands/createAdmin.go b/commands/createAdmin.go new file mode 100644 index 0000000..03a1417 --- /dev/null +++ b/commands/createAdmin.go @@ -0,0 +1,76 @@ +package commands + +import ( + "fmt" + "os" + + "github.com/cosmos/cosmos-sdk/client/builder" + "github.com/cosmos/cosmos-sdk/client/keys" + sdk "github.com/cosmos/cosmos-sdk/types" + wire "github.com/cosmos/cosmos-sdk/wire" + "github.com/spf13/cobra" + "github.com/spf13/viper" + "github.com/tendermint/clearchain/types" +) + +const ( + flagPubKey = "pubkey" + flagEntityName = "entityname" + flagEntityType = "entitytype" + flagSequence = "seq" +) + +type Commander struct { + Cdc *wire.Codec +} + +// GetCreateAdminTxCmd returns a CreateAdminTxCmd. +func GetCreateAdminTxCmd(cdc *wire.Codec) *cobra.Command { + cmdr := Commander{Cdc: cdc} + cmd := &cobra.Command{ + Use: "create-admin", + Short: "Create and sign a CreateAdminTx", + RunE: cmdr.createAdminTxCmd, + Args: cobra.ExactArgs(1), + } + cmd.Flags().String(flagPubKey, "", "New admin's pubkey") + cmd.Flags().String(flagEntityName, "", "New admin's entity name") + cmd.Flags().String(flagEntityType, "", "New admin's entity type (ch|gcm|icm|custodian)") + cmd.Flags().Int64(flagSequence, 0, "Sequence number") + return cmd +} + +func (c Commander) createAdminTxCmd(cmd *cobra.Command, args []string) error { + name := args[0] + keybase, err := keys.GetKeyBase() + if err != nil { + return nil + } + info, err := keybase.Get(name) + if err != nil { + return err + } + creator := info.PubKey.Address() + msg, err := BuildCreateAdminMsg(creator, viper.GetString(flagEntityName), viper.GetString(flagEntityType), viper.GetString(flagPubKey)) + if err != nil { + return err + } + + res, err := builder.SignBuildBroadcast(name, msg, c.Cdc) + if err != nil { + return err + } + fmt.Fprintf(os.Stderr, "Committed at block %d. Hash: %s\n", res.Height, res.Hash.String()) + return nil + +} + +// BuildCreateAdminMsg makes a new CreateAdminMsg. +func BuildCreateAdminMsg(creator sdk.Address, entityName, entityType, pubKey string) (sdk.Msg, error) { + // parse new account pubkey + pub, err := types.PubKeyFromHexString(pubKey) + if err != nil { + return nil, err + } + return types.NewCreateAdminMsg(creator, pub, entityName, entityType), nil +} diff --git a/commands/createAsset.go b/commands/createAsset.go new file mode 100644 index 0000000..caea462 --- /dev/null +++ b/commands/createAsset.go @@ -0,0 +1,63 @@ +package commands + +import ( + "fmt" + "os" + + "github.com/cosmos/cosmos-sdk/client/builder" + "github.com/cosmos/cosmos-sdk/client/keys" + sdk "github.com/cosmos/cosmos-sdk/types" + wire "github.com/cosmos/cosmos-sdk/wire" + "github.com/spf13/cobra" + "github.com/spf13/viper" + "github.com/tendermint/clearchain/types" +) + +// GetCreateAssetAccountTxCmd returns a createAssetAccountTxCmd. +func GetCreateAssetAccountTxCmd(cdc *wire.Codec) *cobra.Command { + cmdr := Commander{Cdc: cdc} + cmd := &cobra.Command{ + Use: "create-asset", + Short: "Create and sign a CreateAssetAccountTx", + RunE: cmdr.createAssetAccountTxCmd, + Args: cobra.ExactArgs(1), + } + cmd.Flags().String(flagPubKey, "", "New assset account's pubkey") + cmd.Flags().Int64(flagSequence, 0, "Sequence number") + return cmd +} + +func (c Commander) createAssetAccountTxCmd(cmd *cobra.Command, args []string) error { + name := args[0] + keybase, err := keys.GetKeyBase() + if err != nil { + return nil + } + info, err := keybase.Get(name) + if err != nil { + return err + } + creator := info.PubKey.Address() + msg, err := buildCreateAssetAccountMsg(creator) + if err != nil { + return err + } + + res, err := builder.SignBuildBroadcast(name, msg, c.Cdc) + if err != nil { + return err + } + fmt.Fprintf(os.Stderr, "Committed at block %d. Hash: %s\n", res.Height, res.Hash.String()) + return nil + +} + +func buildCreateAssetAccountMsg(creator sdk.Address) (sdk.Msg, error) { + // parse new account pubkey + pubKey, err := types.PubKeyFromHexString(viper.GetString(flagPubKey)) + if err != nil { + return nil, err + } + msg := types.NewCreateAssetAccountMsg(creator, pubKey) + return msg, nil +} diff --git a/commands/createOperator.go b/commands/createOperator.go new file mode 100644 index 0000000..bf5b5ab --- /dev/null +++ b/commands/createOperator.go @@ -0,0 +1,63 @@ +package commands + +import ( + "fmt" + "os" + + "github.com/cosmos/cosmos-sdk/client/builder" + "github.com/cosmos/cosmos-sdk/client/keys" + sdk "github.com/cosmos/cosmos-sdk/types" + wire "github.com/cosmos/cosmos-sdk/wire" + "github.com/spf13/cobra" + "github.com/spf13/viper" + "github.com/tendermint/clearchain/types" +) + +// GetCreateOperatorTxCmd returns a createOperatorTxCmd. +func GetCreateOperatorTxCmd(cdc *wire.Codec) *cobra.Command { + cmdr := Commander{Cdc: cdc} + cmd := &cobra.Command{ + Use: "create-operator", + Short: "Create and sign a CreateOperatorTx", + RunE: cmdr.createOperatorTxCmd, + Args: cobra.ExactArgs(1), + } + cmd.Flags().String(flagPubKey, "", "New operator's pubkey") + cmd.Flags().Int64(flagSequence, 0, "Sequence number") + return cmd +} + +func (c Commander) createOperatorTxCmd(cmd *cobra.Command, args []string) error { + name := args[0] + keybase, err := keys.GetKeyBase() + if err != nil { + return nil + } + info, err := keybase.Get(name) + if err != nil { + return err + } + creator := info.PubKey.Address() + msg, err := buildCreateOperatorMsg(creator) + if err != nil { + return err + } + + res, err := builder.SignBuildBroadcast(name, msg, c.Cdc) + if err != nil { + return err + } + fmt.Fprintf(os.Stderr, "Committed at block %d. Hash: %s\n", res.Height, res.Hash.String()) + return nil + +} + +func buildCreateOperatorMsg(creator sdk.Address) (sdk.Msg, error) { + // parse new account pubkey + pubKey, err := types.PubKeyFromHexString(viper.GetString(flagPubKey)) + if err != nil { + return nil, err + } + msg := types.NewCreateOperatorMsg(creator, pubKey) + return msg, nil +} diff --git a/commands/exportPub.go b/commands/exportPub.go new file mode 100644 index 0000000..9abb0c7 --- /dev/null +++ b/commands/exportPub.go @@ -0,0 +1,62 @@ +package commands + +import ( + "encoding/hex" + "fmt" + + "github.com/spf13/viper" + + "github.com/cosmos/cosmos-sdk/client/keys" + wire "github.com/cosmos/cosmos-sdk/wire" + "github.com/pkg/errors" + "github.com/spf13/cobra" +) + +const ( + flagFormat = "format" +) + +func GetExportPubCmd(cdc *wire.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "export-pub", + RunE: exportPubCmd, + } + cmd.Flags().String(flagFormat, "", "Alternative output format (armor|json)") + return cmd +} + +func exportPubCmd(cmd *cobra.Command, args []string) error { + if len(args) < 1 { + return fmt.Errorf("insufficient arguments") + } + if len(args) > 1 { + return fmt.Errorf("too many arguments: %v", args) + } + name := args[0] + keybase, err := keys.GetKeyBase() + if err != nil { + return err + } + if viper.GetString(flagFormat) == "armor" { + out, err := keybase.Export(name) + if err != nil { + return err + } + fmt.Println(out) + return nil + } + info, err := keybase.Get(name) + if err != nil { + return errors.Errorf("No key for: %s", name) + } + if viper.GetString(flagFormat) == "json" { + out, err := info.PubKey.MarshalJSON() + if err != nil { + return err + } + fmt.Println(string(out)) + return nil + } + fmt.Println(hex.EncodeToString(info.PubKey.Bytes())) + return nil +} diff --git a/commands/version.go b/commands/version.go new file mode 100644 index 0000000..ccb548a --- /dev/null +++ b/commands/version.go @@ -0,0 +1,27 @@ +package commands + +import ( + "fmt" + "os" + + "github.com/spf13/cobra" + "github.com/tendermint/clearchain" +) + +var ( + // VersionCmd prints the program's version to stderr and exits. + VersionCmd = &cobra.Command{ + Use: "version", + Short: "Print clearchain's version", + Run: doVersionCmd, + } +) + +func doVersionCmd(cmd *cobra.Command, args []string) { + v := clearchain.Version + if len(v) == 0 { + fmt.Fprintln(os.Stderr, "unset") + return + } + fmt.Fprintln(os.Stderr, v) +} diff --git a/glide.lock b/glide.lock deleted file mode 100644 index 6869661..0000000 --- a/glide.lock +++ /dev/null @@ -1,269 +0,0 @@ -hash: 5be84d38d30b475ce93b5a031c190e993f7fb31b90de088ec97718acaf2cdc0c -updated: 2018-03-18T12:48:18.097135924Z -imports: -- name: github.com/bgentry/speakeasy - version: 4aabc24848ce5fd31929f7d1e4ea74d3709c14cd -- name: github.com/btcsuite/btcd - version: 2be2f12b358dc57d70b8f501b00be450192efbc3 - subpackages: - - btcec -- name: github.com/cosmos/cosmos-sdk - version: f4c2b504f4be858dd893e990ea2df24c3564f5ae - subpackages: - - baseapp - - client - - client/keys - - client/lcd - - client/rpc - - client/tx - - examples/basecoin/app - - examples/basecoin/types - - examples/basecoin/x/sketchy - - server - - store - - types - - version - - x/auth - - x/auth/commands - - x/bank -- name: github.com/davecgh/go-spew - version: 346938d642f2ec3594ed81d874461961cd0faa76 - subpackages: - - spew -- name: github.com/ebuchman/fail-test - version: 95f809107225be108efcf10a3509e4ea6ceef3c4 -- name: github.com/fsnotify/fsnotify - version: c2828203cd70a50dcccfb2761f8b1f8ceef9a8e9 -- name: github.com/go-kit/kit - version: 4dc7be5d2d12881735283bcab7352178e190fc71 - subpackages: - - log - - log/level - - log/term -- name: github.com/go-logfmt/logfmt - version: 390ab7935ee28ec6b286364bba9b4dd6410cb3d5 -- name: github.com/go-stack/stack - version: 259ab82a6cad3992b4e21ff5cac294ccb06474bc -- name: github.com/gogo/protobuf - version: 1adfc126b41513cc696b209667c8656ea7aac67c - subpackages: - - gogoproto - - jsonpb - - proto - - protoc-gen-gogo/descriptor - - sortkeys - - types -- name: github.com/golang/protobuf - version: 925541529c1fa6821df4e44ce2723319eb2be768 - subpackages: - - proto - - ptypes - - ptypes/any - - ptypes/duration - - ptypes/timestamp -- name: github.com/golang/snappy - version: 553a641470496b2327abcac10b36396bd98e45c9 -- name: github.com/gorilla/websocket - version: ea4d1f681babbce9545c9c5f3d5194a789c89f5b -- name: github.com/hashicorp/hcl - version: 23c074d0eceb2b8a5bfdbb271ab780cde70f05a8 - subpackages: - - hcl/ast - - hcl/parser - - hcl/scanner - - hcl/strconv - - hcl/token - - json/parser - - json/scanner - - json/token -- name: github.com/howeyc/crc16 - version: 96a97a1abb579c7ff1a8ffa77f2e72d1c314b57f -- name: github.com/inconshreveable/mousetrap - version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 -- name: github.com/jmhodges/levigo - version: c42d9e0ca023e2198120196f842701bb4c55d7b9 -- name: github.com/kr/logfmt - version: b84e30acd515aadc4b783ad4ff83aff3299bdfe0 -- name: github.com/magiconair/properties - version: 49d762b9817ba1c2e9d0c69183c2b4a8b8f1d934 -- name: github.com/mattn/go-isatty - version: 0360b2af4f38e8d38c7fce2a9f4e702702d73a39 -- name: github.com/mitchellh/mapstructure - version: b4575eea38cca1123ec2dc90c26529b5c5acfcff -- name: github.com/pelletier/go-toml - version: acdc4509485b587f5e675510c4f2c63e90ff68a8 -- name: github.com/pkg/errors - version: 645ef00459ed84a119197bfb8d8205042c6df63d -- name: github.com/rcrowley/go-metrics - version: 1f30fe9094a513ce4c700b9a54458bbb0c96996c -- name: github.com/spf13/afero - version: bb8f1927f2a9d3ab41c9340aa034f6b803f4359c - subpackages: - - mem -- name: github.com/spf13/cast - version: acbeb36b902d72a7a4c18e8f3241075e7ab763e4 -- name: github.com/spf13/cobra - version: 7b2c5ac9fc04fc5efafb60700713d4fa609b777b -- name: github.com/spf13/jwalterweatherman - version: 7c0cea34c8ece3fbeb2b27ab9b59511d360fb394 -- name: github.com/spf13/pflag - version: e57e3eeb33f795204c1ca35f56c44f83227c6e66 -- name: github.com/spf13/viper - version: 25b30aa063fc18e48662b86996252eabdcf2f0c7 -- name: github.com/syndtr/goleveldb - version: 211f780988068502fe874c44dae530528ebd840f - subpackages: - - leveldb - - leveldb/cache - - leveldb/comparer - - leveldb/errors - - leveldb/filter - - leveldb/iterator - - leveldb/journal - - leveldb/memdb - - leveldb/opt - - leveldb/storage - - leveldb/table - - leveldb/util -- name: github.com/tendermint/abci - version: 68592f4d8ee34e97db94b7a7976b1309efdb7eb9 - subpackages: - - client - - example/code - - example/dummy - - server - - types -- name: github.com/tendermint/ed25519 - version: d8387025d2b9d158cf4efb07e7ebf814bcce2057 - subpackages: - - edwards25519 - - extra25519 -- name: github.com/tendermint/go-crypto - version: 4fc3055dbd17aa1203d0abc64b9293f378da22ec - subpackages: - - keys - - keys/bcrypt - - keys/words - - keys/words/wordlist -- name: github.com/tendermint/go-wire - version: 5d7845f24b843c914cf571dad2ca13c91cf70f0d -- name: github.com/tendermint/iavl - version: 1a59ec0c82dc940c25339dd7c834df5cb76a95cb -- name: github.com/tendermint/tendermint - version: c330b9e43c93351a5c3040333d7d0c7c27859a20 - subpackages: - - blockchain - - cmd/tendermint/commands - - config - - consensus - - consensus/types - - evidence - - lite - - lite/client - - lite/errors - - lite/files - - lite/proxy - - mempool - - node - - p2p - - p2p/conn - - p2p/pex - - p2p/trust - - p2p/upnp - - proxy - - rpc/client - - rpc/core - - rpc/core/types - - rpc/grpc - - rpc/lib - - rpc/lib/client - - rpc/lib/server - - rpc/lib/types - - state - - state/txindex - - state/txindex/kv - - state/txindex/null - - types - - version - - wire -- name: github.com/tendermint/tmlibs - version: 26f2ab65f82cfc6873c312e8030104c47c05f10e - subpackages: - - autofile - - cli - - cli/flags - - clist - - common - - db - - flowrate - - log - - merkle - - pubsub - - pubsub/query -- name: golang.org/x/crypto - version: 432090b8f568c018896cd8a0fb0345872bbac6ce - subpackages: - - blowfish - - curve25519 - - nacl/box - - nacl/secretbox - - openpgp/armor - - openpgp/errors - - poly1305 - - ripemd160 - - salsa20/salsa -- name: golang.org/x/net - version: cbe0f9307d0156177f9dd5dc85da1a31abc5f2fb - subpackages: - - context - - http2 - - http2/hpack - - idna - - internal/timeseries - - lex/httplex - - trace -- name: golang.org/x/sys - version: 37707fdb30a5b38865cfb95e5aab41707daec7fd - subpackages: - - unix -- name: golang.org/x/text - version: 9e2b64d659da1afe07ce1c9c1dfefc09d188f21e - subpackages: - - secure/bidirule - - transform - - unicode/bidi - - unicode/norm -- name: google.golang.org/genproto - version: 2b5a72b8730b0b16380010cfe5286c42108d88e7 - subpackages: - - googleapis/rpc/status -- name: google.golang.org/grpc - version: 401e0e00e4bb830a10496d64cd95e068c5bf50de - subpackages: - - balancer - - codes - - connectivity - - credentials - - grpclb/grpc_lb_v1/messages - - grpclog - - internal - - keepalive - - metadata - - naming - - peer - - resolver - - stats - - status - - tap - - transport -- name: gopkg.in/yaml.v2 - version: d670f9405373e636a5a2765eea47fac0c9bc91a4 -testImports: -- name: github.com/pmezard/go-difflib - version: 792786c7400a136282c1664665ae0a8db921c6c2 - subpackages: - - difflib -- name: github.com/stretchr/testify - version: 12b6f73e6084dad08a7c6e575284b177ecafbc71 - subpackages: - - assert diff --git a/glide.yaml b/glide.yaml deleted file mode 100644 index e920ab7..0000000 --- a/glide.yaml +++ /dev/null @@ -1,41 +0,0 @@ -package: github.com/tendermint/clearchain -import: -- package: github.com/cosmos/cosmos-sdk - version: v0.11.0 -- package: github.com/tendermint/go-crypto - version: 4fc3055dbd17aa1203d0abc64b9293f378da22ec -- package: github.com/tendermint/tendermint - version: c330b9e43c93351a5c3040333d7d0c7c27859a20 - subpackages: - - cmd/tendermint/commands - - config - - lite - - rpc/client - - types -- package: github.com/tendermint/tmlibs - version: 26f2ab65f82cfc6873c312e8030104c47c05f10e - subpackages: - - autofile - - cli - - cli/flags - - clist - - common - - db - - flowrate - - log - - merkle - - pubsub - - pubsub/query -- package: github.com/tendermint/go-wire - version: 5d7845f24b843c914cf571dad2ca13c91cf70f0d -- package: github.com/tendermint/iavl - version: 1a59ec0c82dc940c25339dd7c834df5cb76a95cb -- package: github.com/tendermint/abci - version: 68592f4d8ee34e97db94b7a7976b1309efdb7eb9 - subpackages: - - client - - server - - types -testImport: -- package: github.com/stretchr/testify - version: ^1.2.0 diff --git a/types/account.go b/types/account.go index 67de2b6..8a0fffa 100644 --- a/types/account.go +++ b/types/account.go @@ -4,8 +4,9 @@ import ( "bytes" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/x/auth" - crypto "github.com/tendermint/go-crypto" + "github.com/tendermint/go-crypto" ) // EntityType string identifiers @@ -18,55 +19,52 @@ const ( var ( _ sdk.Account = (*AppAccount)(nil) _ LegalEntity = (*AppAccount)(nil) - _ UserAccount = (*AppAccount)(nil) ) -// UserAccount is the interface that wraps the basic -// accessor methods to set and get user accounts attributes. -type UserAccount interface { - GetAccountType() string - IsAdmin() bool - IsActive() bool -} - // AppAccount defines the properties of an AppAccount. type AppAccount struct { auth.BaseAccount BaseLegalEntity - Creator crypto.Address + Creator sdk.Address AccountType string Active bool Admin bool } // NewAppAccount constructs a new account instance. -func newAppAccount(pub crypto.PubKey, cash sdk.Coins, creator crypto.Address, typ string, +func newAppAccount(pub crypto.PubKey, cash sdk.Coins, creator sdk.Address, typ string, isActive bool, isAdmin bool, entityName, entityType string) *AppAccount { - acct := new(AppAccount) - acct.SetAddress(pub.Address()) - acct.SetPubKey(pub) - acct.SetCoins(cash) - acct.Creator = creator - acct.EntityName = entityName - acct.EntityType = entityType - acct.AccountType = typ - acct.Active = isActive - acct.Admin = isAdmin - return acct + baseaccount := auth.BaseAccount{ + Address: pub.Address(), + PubKey: pub, + Coins: cash, + } + entity := BaseLegalEntity{ + EntityName: entityName, + EntityType: entityType, + } + return &AppAccount{ + BaseAccount: baseaccount, + BaseLegalEntity: entity, + Creator: creator, + AccountType: typ, + Active: isActive, + Admin: isAdmin, + } } // NewOpUser constructs a new account instance, setting cash to nil. -func NewOpUser(pub crypto.PubKey, creator crypto.Address, entityName, entityType string) *AppAccount { +func NewOpUser(pub crypto.PubKey, creator sdk.Address, entityName, entityType string) *AppAccount { return newAppAccount(pub, nil, creator, AccountUser, true, false, entityName, entityType) } // NewAdminUser constructs a new account instance, setting cash to nil. -func NewAdminUser(pub crypto.PubKey, creator crypto.Address, entityName, entityType string) *AppAccount { +func NewAdminUser(pub crypto.PubKey, creator sdk.Address, entityName, entityType string) *AppAccount { return newAppAccount(pub, nil, creator, AccountUser, true, true, entityName, entityType) } // NewAssetAccount constructs a new account instance. -func NewAssetAccount(pub crypto.PubKey, cash sdk.Coins, creator crypto.Address, entityName, entityType string) *AppAccount { +func NewAssetAccount(pub crypto.PubKey, cash sdk.Coins, creator sdk.Address, entityName, entityType string) *AppAccount { return newAppAccount(pub, cash, creator, AccountAsset, true, false, entityName, entityType) } @@ -86,33 +84,37 @@ func (a AppAccount) IsAdmin() bool { } // IsUser returns true if the account holds user data; false otherwise. -func IsUser(a UserAccount) bool { +func (a AppAccount) IsUser() bool { return a.GetAccountType() == AccountUser } // IsAsset returns true if the account holds assets; false otherwise. -func IsAsset(a UserAccount) bool { +func (a AppAccount) IsAsset() bool { return a.GetAccountType() == AccountAsset } -// AccountMapper creates an account mapper given a storekey -func AccountMapper(capKey sdk.StoreKey) sdk.AccountMapper { - var accountMapper = auth.NewAccountMapper( - capKey, // target store - &AppAccount{}, // prototype - ) - - // Register all interfaces and concrete types that - // implement those interfaces, here. - cdc := accountMapper.WireCodec() - crypto.RegisterWire(cdc) - // auth.RegisterWireBaseAccount(cdc) - - // Make WireCodec inaccessible before sealing - res := accountMapper.Seal() - return res +// NewAccountMapper creates an account mapper given a storekey +func NewAccountMapper(capKey sdk.StoreKey) sdk.AccountMapper { + return auth.NewAccountMapperSealed(capKey, &AppAccount{}) } +// Get the AccountDecoder function for the custom AppAccount +func GetAccountDecoder(cdc *wire.Codec) sdk.AccountDecoder { + return func(accBytes []byte) (res sdk.Account, err error) { + if len(accBytes) == 0 { + return nil, sdk.ErrTxDecode("accBytes are empty") + } + acct := new(AppAccount) + err = cdc.UnmarshalBinary(accBytes, &acct) + if err != nil { + panic(err) + } + return acct, err + } +} + +/* auxiliary functions */ + func accountEqual(a1, a2 *AppAccount) bool { return ((a1.AccountType == a2.AccountType) && (a1.Admin == a2.Admin) && diff --git a/types/account_test.go b/types/account_test.go index 067d294..0ecc6b0 100644 --- a/types/account_test.go +++ b/types/account_test.go @@ -65,15 +65,41 @@ func Test_sliceContainsString(t *testing.T) { func makeUser(entname, typ string) (*AppAccount, crypto.PrivKey) { priv := crypto.GenPrivKeyEd25519() - return NewOpUser(priv.PubKey(), nil, entname, typ), priv + return NewOpUser(priv.PubKey(), nil, entname, typ), priv.Wrap() } func makeAdminUser(entname, typ string) (*AppAccount, crypto.PrivKey) { priv := crypto.GenPrivKeyEd25519() - return NewAdminUser(priv.PubKey(), nil, entname, typ), priv + return NewAdminUser(priv.PubKey(), nil, entname, typ), priv.Wrap() } func makeAssetAccount(cash sdk.Coins, entname, typ string) (*AppAccount, crypto.Address) { pub := crypto.GenPrivKeyEd25519().PubKey() return NewAssetAccount(pub, cash, nil, entname, typ), pub.Address() } + +func TestGetAccountDecoder(t *testing.T) { + cdc := MakeCodec() + decoder := GetAccountDecoder(cdc) + admin, _ := makeAdminUser("member", "gcm") + adminBz, _ := cdc.MarshalBinary(admin) + tests := []struct { + name string + account *AppAccount + bz []byte + wantErr bool + }{ + {"admin", admin, adminBz, false}, + {"nil", &AppAccount{}, []byte{}, true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + acct, err := decoder(tt.bz) + assert.Equal(t, tt.wantErr, err != nil) + if err == nil { + concreteAcct := acct.(*AppAccount) + assert.True(t, accountEqual(concreteAcct, tt.account)) + } + }) + } +} diff --git a/types/ccy.go b/types/ccy.go new file mode 100644 index 0000000..8f60559 --- /dev/null +++ b/types/ccy.go @@ -0,0 +1,203 @@ +package types + +var ( + // Currencies contains the in-memory database of supported currencies + currencies map[string]ccy +) + +type ccy struct { + decimalPlaces uint + minimumUnit int64 + denom string +} + +func init() { + currencies = make(map[string]ccy) + currencyData := []struct { + d uint + m int64 + s string + }{ + {2, 1, "AED"}, + {2, 1, "AFN"}, + {2, 1, "ALL"}, + {2, 1, "AMD"}, + {2, 1, "ANG"}, + {2, 1, "AOA"}, + {2, 1, "ARS"}, + {2, 1, "AUD"}, + {2, 1, "AWG"}, + {2, 1, "AZN"}, + {2, 1, "BAM"}, + {2, 1, "BBD"}, + {2, 1, "BDT"}, + {2, 1, "BGN"}, + {3, 1, "BHD"}, + {0, 1, "BIF"}, + {2, 1, "BMD"}, + {2, 1, "BND"}, + {2, 1, "BOB"}, + {2, 1, "BOV"}, + {2, 1, "BRL"}, + {2, 1, "BSD"}, + {2, 1, "BTN"}, + {2, 1, "BWP"}, + {2, 1, "BYN"}, + {0, 1, "BYR"}, + {2, 1, "BZD"}, + {2, 1, "CAD"}, + {2, 1, "CDF"}, + {2, 1, "CHE"}, + {2, 1, "CHF"}, + {2, 1, "CHW"}, + {4, 1, "CLF"}, + {0, 1, "CLP"}, + {2, 1, "CNY"}, + {2, 1, "COP"}, + {2, 1, "COU"}, + {2, 1, "CRC"}, + {2, 1, "CUC"}, + {2, 1, "CUP"}, + {0, 1, "CVE"}, + {2, 1, "CZK"}, + {0, 1, "DJF"}, + {2, 1, "DKK"}, + {2, 1, "DOP"}, + {2, 1, "DZD"}, + {2, 1, "EGP"}, + {2, 1, "ERN"}, + {2, 1, "ETB"}, + {2, 1, "EUR"}, + {2, 1, "FJD"}, + {2, 1, "FKP"}, + {2, 1, "GBP"}, + {2, 1, "GEL"}, + {2, 1, "GHS"}, + {2, 1, "GIP"}, + {2, 1, "GMD"}, + {0, 1, "GNF"}, + {2, 1, "GTQ"}, + {2, 1, "GYD"}, + {2, 1, "HKD"}, + {2, 1, "HNL"}, + {2, 1, "HRK"}, + {2, 1, "HTG"}, + {2, 1, "HUF"}, + {2, 1, "IDR"}, + {2, 1, "ILS"}, + {2, 1, "INR"}, + {3, 1, "IQD"}, + {2, 1, "IRR"}, + {0, 1, "ISK"}, + {2, 1, "JMD"}, + {3, 1, "JOD"}, + {0, 1, "JPY"}, + {2, 1, "KES"}, + {2, 1, "KGS"}, + {2, 1, "KHR"}, + {0, 1, "KMF"}, + {2, 1, "KPW"}, + {0, 1, "KRW"}, + {3, 1, "KWD"}, + {2, 1, "KYD"}, + {2, 1, "KZT"}, + {2, 1, "LAK"}, + {2, 1, "LBP"}, + {2, 1, "LKR"}, + {2, 1, "LRD"}, + {2, 1, "LSL"}, + {3, 1, "LYD"}, + {2, 1, "MAD"}, + {2, 1, "MDL"}, + {1, 1, "MGA"}, + {2, 1, "MKD"}, + {2, 1, "MMK"}, + {2, 1, "MNT"}, + {2, 1, "MOP"}, + {1, 1, "MRO"}, + {2, 1, "MUR"}, + {2, 1, "MVR"}, + {2, 1, "MWK"}, + {2, 1, "MXN"}, + {2, 1, "MXV"}, + {2, 1, "MYR"}, + {2, 1, "MZN"}, + {2, 1, "NAD"}, + {2, 1, "NGN"}, + {2, 1, "NIO"}, + {2, 1, "NOK"}, + {2, 1, "NPR"}, + {2, 1, "NZD"}, + {3, 1, "OMR"}, + {2, 1, "PAB"}, + {2, 1, "PEN"}, + {2, 1, "PGK"}, + {2, 1, "PHP"}, + {2, 1, "PKR"}, + {2, 1, "PLN"}, + {0, 1, "PYG"}, + {2, 1, "QAR"}, + {2, 1, "RON"}, + {2, 1, "RSD"}, + {2, 1, "RUB"}, + {0, 1, "RWF"}, + {2, 1, "SAR"}, + {2, 1, "SBD"}, + {2, 1, "SCR"}, + {2, 1, "SDG"}, + {2, 1, "SEK"}, + {2, 1, "SGD"}, + {2, 1, "SHP"}, + {2, 1, "SLL"}, + {2, 1, "SOS"}, + {2, 1, "SRD"}, + {2, 1, "SSP"}, + {2, 1, "STD"}, + {2, 1, "SVC"}, + {2, 1, "SYP"}, + {2, 1, "SZL"}, + {2, 1, "THB"}, + {2, 1, "TJS"}, + {2, 1, "TMT"}, + {3, 1, "TND"}, + {2, 1, "TOP"}, + {2, 1, "TRY"}, + {2, 1, "TTD"}, + {2, 1, "TWD"}, + {2, 1, "TZS"}, + {2, 1, "UAH"}, + {0, 1, "UGX"}, + {2, 1, "USD"}, + {2, 1, "USN"}, + {0, 1, "UYI"}, + {2, 1, "UYU"}, + {2, 1, "UZS"}, + {2, 1, "VEF"}, + {0, 1, "VND"}, + {0, 1, "VUV"}, + {2, 1, "WST"}, + {0, 1, "XAF"}, + {2, 1, "XCD"}, + {0, 1, "XOF"}, + {0, 1, "XPF"}, + {2, 1, "YER"}, + {2, 1, "ZAR"}, + {2, 1, "ZMW"}, + {2, 1, "ZWL"}, + } + for _, d := range currencyData { + currencies[d.s] = ccy{decimalPlaces: d.d, minimumUnit: d.m, denom: d.s} + } +} + +func Currencies() (ccys []string) { + for k := range currencies { + ccys = append(ccys, k) + } + return +} + +func ValidateDenom(denom string) bool { + _, ok := currencies[denom] + return ok +} diff --git a/types/ccy_test.go b/types/ccy_test.go new file mode 100644 index 0000000..4cc9f8d --- /dev/null +++ b/types/ccy_test.go @@ -0,0 +1,202 @@ +package types + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestCurrencies(t *testing.T) { + allCurrencies := []string{ + "AED", + "AFN", + "ALL", + "AMD", + "ANG", + "AOA", + "ARS", + "AUD", + "AWG", + "AZN", + "BAM", + "BBD", + "BDT", + "BGN", + "BHD", + "BIF", + "BMD", + "BND", + "BOB", + "BOV", + "BRL", + "BSD", + "BTN", + "BWP", + "BYN", + "BYR", + "BZD", + "CAD", + "CDF", + "CHE", + "CHF", + "CHW", + "CLF", + "CLP", + "CNY", + "COP", + "COU", + "CRC", + "CUC", + "CUP", + "CVE", + "CZK", + "DJF", + "DKK", + "DOP", + "DZD", + "EGP", + "ERN", + "ETB", + "EUR", + "FJD", + "FKP", + "GBP", + "GEL", + "GHS", + "GIP", + "GMD", + "GNF", + "GTQ", + "GYD", + "HKD", + "HNL", + "HRK", + "HTG", + "HUF", + "IDR", + "ILS", + "INR", + "IQD", + "IRR", + "ISK", + "JMD", + "JOD", + "JPY", + "KES", + "KGS", + "KHR", + "KMF", + "KPW", + "KRW", + "KWD", + "KYD", + "KZT", + "LAK", + "LBP", + "LKR", + "LRD", + "LSL", + "LYD", + "MAD", + "MDL", + "MGA", + "MKD", + "MMK", + "MNT", + "MOP", + "MRO", + "MUR", + "MVR", + "MWK", + "MXN", + "MXV", + "MYR", + "MZN", + "NAD", + "NGN", + "NIO", + "NOK", + "NPR", + "NZD", + "OMR", + "PAB", + "PEN", + "PGK", + "PHP", + "PKR", + "PLN", + "PYG", + "QAR", + "RON", + "RSD", + "RUB", + "RWF", + "SAR", + "SBD", + "SCR", + "SDG", + "SEK", + "SGD", + "SHP", + "SLL", + "SOS", + "SRD", + "SSP", + "STD", + "SVC", + "SYP", + "SZL", + "THB", + "TJS", + "TMT", + "TND", + "TOP", + "TRY", + "TTD", + "TWD", + "TZS", + "UAH", + "UGX", + "USD", + "USN", + "UYI", + "UYU", + "UZS", + "VEF", + "VND", + "VUV", + "WST", + "XAF", + "XCD", + "XOF", + "XPF", + "YER", + "ZAR", + "ZMW", + "ZWL", + } + got := Currencies() + assert.ElementsMatch(t, got, allCurrencies) +} + +func TestValidateDenom(t *testing.T) { + type args struct { + denom string + } + tests := []struct { + name string + args args + want bool + }{ + {"empty", args{""}, false}, + {"USD", args{"USD"}, true}, + {"wrong", args{"wrong"}, false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ValidateDenom(tt.args.denom); got != tt.want { + t.Errorf("ValidateDenom() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/types/genesis.go b/types/genesis.go index da77959..88dea9f 100644 --- a/types/genesis.go +++ b/types/genesis.go @@ -32,3 +32,13 @@ func (ga *GenesisAccount) ToClearingHouseAdmin() (acc *AppAccount, err error) { adminUser := NewAdminUser(publicKey, nil, ga.EntityName, EntityClearingHouse) return adminUser, nil } + +// PubKeyFromHexString converts a hexadecimal string representation of +// a public key into a crypto.PubKey instance. +func PubKeyFromHexString(s string) (crypto.PubKey, error) { + bytes, err := hex.DecodeString(s) + if err != nil { + return crypto.PubKey{}, err + } + return crypto.PubKeyFromBytes(bytes) +} diff --git a/types/genesis_test.go b/types/genesis_test.go index 89f2ed4..dcd926c 100644 --- a/types/genesis_test.go +++ b/types/genesis_test.go @@ -4,22 +4,23 @@ import ( "encoding/hex" "testing" + "github.com/cosmos/cosmos-sdk/wire" "github.com/stretchr/testify/assert" - crypto "github.com/tendermint/go-crypto" ) // ToClearingHouseAdmin verifies that a GenesisAccount is converted correctly into an AppAccount (a Clearing House admin user) func Test_ToClearingHouseAdmin(t *testing.T) { cdc := MakeCodec() + wire.RegisterCrypto(cdc) - pubBytes, _ := hex.DecodeString("328eaf59335aa6724f253ca8f1620b249bb83e665d7e5134e9bf92079b2549df3572f874") + pubBytes, _ := hex.DecodeString("01328eaf59335aa6724f253ca8f1620b249bb83e665d7e5134e9bf92079b2549df3572f874") publicKey1, _ := crypto.PubKeyFromBytes(pubBytes) - pubBytes, _ = hex.DecodeString("328eaf59335aa6724f253ca8f1620b249bb83e665d7e5134e9bf92079b2549df3572f875") + pubBytes, _ = hex.DecodeString("01328eaf59335aa6724f253ca8f1620b249bb83e665d7e5134e9bf92079b2549df3572f875") publicKey2, _ := crypto.PubKeyFromBytes(pubBytes) - pubBytes, _ = hex.DecodeString("328eaf59335aa6724f253ca8f1620b249bb83e665d7e5134e9bf92079b2549df3572f876") + pubBytes, _ = hex.DecodeString("01328eaf59335aa6724f253ca8f1620b249bb83e665d7e5134e9bf92079b2549df3572f876") publicKey3, _ := crypto.PubKeyFromBytes(pubBytes) adminCreated1 := NewAdminUser(publicKey1, nil, "ClearChain", "ch") @@ -35,13 +36,13 @@ func Test_ToClearingHouseAdmin(t *testing.T) { expectedAccount *AppAccount }{ { - "instantiate admin 1 ok", args{jsonValue: "{\"public_key\":\"328eaf59335aa6724f253ca8f1620b249bb83e665d7e5134e9bf92079b2549df3572f874\", \"entity_name\":\"ClearChain\"}"}, adminCreated1, + "instantiate admin 1 ok", args{jsonValue: "{\"public_key\":\"01328eaf59335aa6724f253ca8f1620b249bb83e665d7e5134e9bf92079b2549df3572f874\", \"entity_name\":\"ClearChain\"}"}, adminCreated1, }, { - "instantiate admin 2 ok", args{jsonValue: "{\"public_key\":\"328eaf59335aa6724f253ca8f1620b249bb83e665d7e5134e9bf92079b2549df3572f875\", \"entity_name\":\"ClearingHouse\"}"}, adminCreated2, + "instantiate admin 2 ok", args{jsonValue: "{\"public_key\":\"01328eaf59335aa6724f253ca8f1620b249bb83e665d7e5134e9bf92079b2549df3572f875\", \"entity_name\":\"ClearingHouse\"}"}, adminCreated2, }, { - "instantiate admin 3 ok", args{jsonValue: "{\"public_key\":\"328eaf59335aa6724f253ca8f1620b249bb83e665d7e5134e9bf92079b2549df3572f876\", \"entity_name\":\"Admin\"}"}, adminCreated3, + "instantiate admin 3 ok", args{jsonValue: "{\"public_key\":\"01328eaf59335aa6724f253ca8f1620b249bb83e665d7e5134e9bf92079b2549df3572f876\", \"entity_name\":\"Admin\"}"}, adminCreated3, }, } @@ -50,7 +51,8 @@ func Test_ToClearingHouseAdmin(t *testing.T) { var genesisAcc GenesisAccount err := cdc.UnmarshalJSON([]byte(tt.args.jsonValue), &genesisAcc) assert.Nil(t, err) - adminUser, _ := genesisAcc.ToClearingHouseAdmin() + adminUser, err := genesisAcc.ToClearingHouseAdmin() + assert.Nil(t, err) assert.Equal(t, hex.EncodeToString(tt.expectedAccount.Address), hex.EncodeToString(adminUser.Address)) assert.True(t, tt.expectedAccount.PubKey.Equals(adminUser.PubKey)) assert.True(t, adminUser.Coins.IsZero()) @@ -66,3 +68,24 @@ func Test_ToClearingHouseAdmin(t *testing.T) { }) } } + +func TestPubKeyFromHexString(t *testing.T) { + type args struct { + s string + } + tests := []struct { + name string + args args + wantErr bool + }{ + {"good key", args{"01328eaf5937458f6c39c54ee3624137cabe7af88226454fd30180c8da6c711ad6de7f6053"}, false}, + {"bad key", args{"0124137cabe7af88226454fd30180c8da6c711ad6de7f6053"}, true}, + {"nil", args{""}, true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, err := PubKeyFromHexString(tt.args.s) + assert.Equal(t, (err != nil), tt.wantErr) + }) + } +} diff --git a/types/handler.go b/types/handler.go index a3a8f31..6d3c818 100644 --- a/types/handler.go +++ b/types/handler.go @@ -375,7 +375,7 @@ func getUser(ctx sdk.Context, accts sdk.AccountMapper, return nil, ErrInvalidAccount("account does not exist") } account := rawAccount.(*AppAccount) - if !IsUser(account) { + if !account.IsUser() { return nil, ErrWrongSigner("invalid account type") } if wantActive && !account.Active { @@ -403,7 +403,7 @@ func getAsset(ctx sdk.Context, accts sdk.AccountMapper, addr crypto.Address, wan return nil, ErrInvalidAccount("account does not exist") } account := rawAccount.(*AppAccount) - if !IsAsset(account) { + if !account.IsAsset() { return nil, ErrWrongSigner("invalid account type") } if wantActive && !account.Active { diff --git a/types/handler_test.go b/types/handler_test.go index 82b7d9b..a7a71b8 100644 --- a/types/handler_test.go +++ b/types/handler_test.go @@ -42,7 +42,7 @@ func TestRegisterRoutes(t *testing.T) { }{ { "good deposit", args{ctx: ctx, msg: DepositMsg{Operator: op, Sender: cust, Recipient: member, Amount: sdk.Coin{"USD", 5000}}}, - sdk.CodeOK, sdk.Coins{{"USD", -5000}}, sdk.Coins{{"USD", 5000}}, nil, nil, + sdk.CodeOK, sdk.Coins{{"USD", -5000}}, sdk.Coins{{"USD", 5000}}, sdk.Coins{}, sdk.Coins{}, }, { "deposit2", @@ -51,7 +51,7 @@ func TestRegisterRoutes(t *testing.T) { sdk.Coins{{"USD", -12777}}, sdk.Coins{{"USD", 5000}}, sdk.Coins{{"USD", 7777}}, - nil, + sdk.Coins{}, }, { "settlement", @@ -69,7 +69,7 @@ func TestRegisterRoutes(t *testing.T) { sdk.Coins{{"USD", -12777}}, sdk.Coins{{"USD", 8000}}, sdk.Coins{{"USD", 4777}}, - nil, + sdk.Coins{}, }, { "withdraw", @@ -78,7 +78,7 @@ func TestRegisterRoutes(t *testing.T) { sdk.Coins{{"USD", -7277}}, sdk.Coins{{"USD", 2500}}, sdk.Coins{{"USD", 4777}}, - nil, + sdk.Coins{}, }, } @@ -129,15 +129,15 @@ func Test_depositMsgHandler_Do(t *testing.T) { }{ { "admins ain't allowed", args{ctx: ctx, msg: DepositMsg{Operator: chAdmAddr, Sender: cust, - Recipient: member, Amount: sdk.Coin{"USD", 700}}}, CodeWrongSigner, cCoins, nil, + Recipient: member, Amount: sdk.Coin{"USD", 700}}}, CodeWrongSigner, cCoins, sdk.Coins{}, }, { "inactive operator", args{ctx: ctx, msg: DepositMsg{Operator: inactiveOp.Address, Sender: cust, - Recipient: member, Amount: sdk.Coin{"USD", 700}}}, CodeInactiveAccount, cCoins, nil, + Recipient: member, Amount: sdk.Coin{"USD", 700}}}, CodeInactiveAccount, cCoins, sdk.Coins{}, }, { "no returns", args{ctx: ctx, msg: DepositMsg{Operator: chOp, Sender: member, - Recipient: cust, Amount: sdk.Coin{"USD", 200}}}, CodeWrongSigner, cCoins, nil, // sdk.Coins{} + Recipient: cust, Amount: sdk.Coin{"USD", 200}}}, CodeWrongSigner, cCoins, sdk.Coins{}, // sdk.Coins{} }, { "good deposit", args{ctx: ctx, msg: DepositMsg{Operator: chOp, Sender: cust, Recipient: member, @@ -255,7 +255,7 @@ func Test_withdrawMsgHandler_Do(t *testing.T) { }{ { "no returns", WithdrawMsg{Sender: cust, Recipient: member, Operator: operator, Amount: sdk.Coin{"USD", 200}}, - CodeWrongSigner, nil, mCoins, + CodeWrongSigner, sdk.Coins{}, mCoins, }, { "good Withdraw", WithdrawMsg{Sender: member, Recipient: cust, Operator: operator, Amount: sdk.Coin{"USD", 500}}, @@ -434,7 +434,7 @@ func fakeAccountMapper() (sdk.AccountMapper, sdk.Context) { panic(err) } - accts := AccountMapper(key) + accts := NewAccountMapper(key) h := abci.Header{ Height: 100, ChainID: "clear-chain", diff --git a/types/msgs.go b/types/msgs.go index 382b2ba..b7d8721 100644 --- a/types/msgs.go +++ b/types/msgs.go @@ -2,6 +2,7 @@ package types import ( "bytes" + "encoding/json" "fmt" sdk "github.com/cosmos/cosmos-sdk/types" @@ -22,35 +23,41 @@ const ( FreezeAdminType = "freezeAdmin" ) +const ( + // AddressLength represents the number of bytes that compose addresses. + AddressLength = 20 +) + // DepositMsg defines the properties of an asset transfer type DepositMsg struct { - Operator crypto.Address - Sender crypto.Address - Recipient crypto.Address + Operator sdk.Address + Sender sdk.Address + Recipient sdk.Address Amount sdk.Coin } // ensure DepositMsg implements the sdk.Msg interface +var _ sdk.Msg = DepositMsg{} var _ sdk.Msg = (*DepositMsg)(nil) // ValidateBasic is called by the SDK automatically. -func (d DepositMsg) ValidateBasic() sdk.Error { - if d.Amount.Amount <= 0 { +func (msg DepositMsg) ValidateBasic() sdk.Error { + if msg.Amount.Amount <= 0 { return ErrInvalidAmount("negative amount") } - if d.Amount.Denom == "" { + if msg.Amount.Denom == "" { return ErrInvalidAmount("empty denom") } - if err := validateAddress(d.Operator); err != nil { + if err := validateAddress(msg.Operator); err != nil { return err } - if err := validateAddress(d.Sender); err != nil { + if err := validateAddress(msg.Sender); err != nil { return err } - if err := validateAddress(d.Recipient); err != nil { + if err := validateAddress(msg.Recipient); err != nil { return err } - if bytes.Equal(d.Sender, d.Recipient) { + if bytes.Equal(msg.Sender, msg.Recipient) { return ErrInvalidAddress("sender and recipient have the same address") } return nil @@ -58,14 +65,14 @@ func (d DepositMsg) ValidateBasic() sdk.Error { // Type returns the message type. // Must be alphanumeric or empty. -func (d DepositMsg) Type() string { return DepositType } +func (msg DepositMsg) Type() string { return DepositType } // Get some property of the Msg. -func (d DepositMsg) Get(key interface{}) (value interface{}) { return nil } +func (msg DepositMsg) Get(key interface{}) (value interface{}) { return nil } // GetSignBytes returns the canonical byte representation of the Msg. -func (d DepositMsg) GetSignBytes() []byte { - bz, err := cdc.MarshalBinary(d) +func (msg DepositMsg) GetSignBytes() []byte { + bz, err := json.Marshal(msg) if err != nil { panic(err) } @@ -75,13 +82,13 @@ func (d DepositMsg) GetSignBytes() []byte { // GetSigners returns the addrs of signers that must sign. // CONTRACT: All signatures must be present to be valid. // CONTRACT: Returns addrs in some deterministic order. -func (d DepositMsg) GetSigners() []crypto.Address { return []crypto.Address{d.Operator} } +func (msg DepositMsg) GetSigners() []sdk.Address { return []sdk.Address{msg.Operator} } // SettleMsg defines the properties of a settle transaction. type SettleMsg struct { - Operator crypto.Address - Sender crypto.Address - Recipient crypto.Address + Operator sdk.Address + Sender sdk.Address + Recipient sdk.Address Amount sdk.Coin } @@ -120,7 +127,7 @@ func (msg SettleMsg) Get(key interface{}) (value interface{}) { return nil } // GetSignBytes returns the canonical byte representation of the Msg. func (msg SettleMsg) GetSignBytes() []byte { - bz, err := cdc.MarshalBinary(msg) + bz, err := json.Marshal(msg) if err != nil { panic(err) } @@ -130,13 +137,13 @@ func (msg SettleMsg) GetSignBytes() []byte { // GetSigners returns the addrs of signers that must sign. // CONTRACT: All signatures must be present to be valid. // CONTRACT: Returns addrs in some deterministic order. -func (msg SettleMsg) GetSigners() []crypto.Address { return []crypto.Address{msg.Operator} } +func (msg SettleMsg) GetSigners() []sdk.Address { return []sdk.Address{msg.Operator} } // WithdrawMsg defines the properties of a withdraw transaction. type WithdrawMsg struct { - Operator crypto.Address - Sender crypto.Address - Recipient crypto.Address + Operator sdk.Address + Sender sdk.Address + Recipient sdk.Address Amount sdk.Coin } @@ -174,7 +181,7 @@ func (msg WithdrawMsg) Get(key interface{}) (value interface{}) { return nil } // GetSignBytes returns the canonical byte representation of the Msg. func (msg WithdrawMsg) GetSignBytes() []byte { - bz, err := cdc.MarshalBinary(msg) + bz, err := json.Marshal(msg) if err != nil { panic(err) } @@ -184,11 +191,11 @@ func (msg WithdrawMsg) GetSignBytes() []byte { // GetSigners returns the addrs of signers that must sign. // CONTRACT: All signatures must be present to be valid. // CONTRACT: Returns addrs in some deterministic order. -func (msg WithdrawMsg) GetSigners() []crypto.Address { return []crypto.Address{msg.Operator} } +func (msg WithdrawMsg) GetSigners() []sdk.Address { return []sdk.Address{msg.Operator} } // CreateAssetAccountMsg defines the property of a create user transaction. type CreateAssetAccountMsg struct { - Creator crypto.Address + Creator sdk.Address PubKey crypto.PubKey } @@ -200,7 +207,7 @@ func (msg CreateAssetAccountMsg) ValidateBasic() sdk.Error { if err := validateAddress(msg.Creator); err != nil { return err } - if msg.PubKey == nil { + if msg.PubKey.Empty() { return ErrInvalidPubKey("pub key is nil") } if bytes.Equal(msg.Creator, msg.PubKey.Address()) { @@ -218,7 +225,7 @@ func (msg CreateAssetAccountMsg) Get(key interface{}) (value interface{}) { retu // GetSignBytes returns the canonical byte representation of the Msg. func (msg CreateAssetAccountMsg) GetSignBytes() []byte { - bz, err := cdc.MarshalBinary(msg) + bz, err := json.Marshal(msg) if err != nil { panic(err) } @@ -228,19 +235,19 @@ func (msg CreateAssetAccountMsg) GetSignBytes() []byte { // GetSigners returns the addrs of signers that must sign. // CONTRACT: All signatures must be present to be valid. // CONTRACT: Returns addrs in some deterministic order. -func (msg CreateAssetAccountMsg) GetSigners() []crypto.Address { return []crypto.Address{msg.Creator} } +func (msg CreateAssetAccountMsg) GetSigners() []sdk.Address { return []sdk.Address{msg.Creator} } // BaseCreateUserMsg defines the properties of a transaction // that triggers the creation of a new generic user. // Legal entitiy is inherited from the creator. type BaseCreateUserMsg struct { - Creator crypto.Address + Creator sdk.Address PubKey crypto.PubKey } // ValidateBasic is called by the SDK automatically. func (msg BaseCreateUserMsg) ValidateBasic() sdk.Error { - if msg.PubKey == nil { + if msg.PubKey.Empty() { return ErrInvalidPubKey("pub key is nil") } if err := validateAddress(msg.Creator); err != nil { @@ -261,7 +268,7 @@ func (msg BaseCreateUserMsg) Get(key interface{}) (value interface{}) { return n // GetSignBytes returns the canonical byte representation of the Msg. func (msg BaseCreateUserMsg) GetSignBytes() []byte { - bz, err := cdc.MarshalBinary(msg) + bz, err := json.Marshal(msg) if err != nil { panic(err) } @@ -271,7 +278,7 @@ func (msg BaseCreateUserMsg) GetSignBytes() []byte { // GetSigners returns the addrs of signers that must sign. // CONTRACT: All signatures must be present to be valid. // CONTRACT: Returns addrs in some deterministic order. -func (msg BaseCreateUserMsg) GetSigners() []crypto.Address { return []crypto.Address{msg.Creator} } +func (msg BaseCreateUserMsg) GetSigners() []sdk.Address { return []sdk.Address{msg.Creator} } // CreateOperatorMsg defines the properties of a transaction // that triggers the creation of a new unprivileged user. @@ -313,8 +320,8 @@ func (msg CreateAdminMsg) Type() string { return CreateAdminType } // BaseFreezeAccountMsg defines the properties of a transaction // that freezes user or asset accounts. type BaseFreezeAccountMsg struct { - Admin crypto.Address - Target crypto.Address + Admin sdk.Address + Target sdk.Address } // ValidateBasic is called by the SDK automatically. @@ -339,7 +346,7 @@ func (msg BaseFreezeAccountMsg) Get(key interface{}) (value interface{}) { retur // GetSignBytes returns the canonical byte representation of the Msg. func (msg BaseFreezeAccountMsg) GetSignBytes() []byte { - bz, err := cdc.MarshalBinary(msg) + bz, err := json.Marshal(msg) if err != nil { panic(err) } @@ -349,7 +356,7 @@ func (msg BaseFreezeAccountMsg) GetSignBytes() []byte { // GetSigners returns the addrs of signers that must sign. // CONTRACT: All signatures must be present to be valid. // CONTRACT: Returns addrs in some deterministic order. -func (msg BaseFreezeAccountMsg) GetSigners() []crypto.Address { return []crypto.Address{msg.Admin} } +func (msg BaseFreezeAccountMsg) GetSigners() []sdk.Address { return []sdk.Address{msg.Admin} } // FreezeOperatorMsg defines the properties of a transaction // that freezes an operator. Admin accounts can freeze their @@ -374,13 +381,39 @@ var _ sdk.Msg = (*FreezeAdminMsg)(nil) // Must be alphanumeric or empty. func (msg FreezeAdminMsg) Type() string { return FreezeAdminType } +/* Constructors */ + +// NewCreateAdminMsg creates a new CreateAdminMsg. +func NewCreateAdminMsg(creator sdk.Address, pubkey crypto.PubKey, + entityName, entityType string) (msg CreateAdminMsg) { + msg.BaseCreateUserMsg.Creator = creator + msg.BaseCreateUserMsg.PubKey = pubkey + msg.BaseLegalEntity.EntityName = entityName + msg.BaseLegalEntity.EntityType = entityType + return +} + +// NewCreateOperatorMsg creates a new CreateOperatorMsg. +func NewCreateOperatorMsg(creator sdk.Address, pubkey crypto.PubKey) (msg CreateOperatorMsg) { + msg.BaseCreateUserMsg.Creator = creator + msg.BaseCreateUserMsg.PubKey = pubkey + return +} + +// NewCreateAssetAccountMsg creates a new CreateAssetAccountMsg. +func NewCreateAssetAccountMsg(creator sdk.Address, pubkey crypto.PubKey) (msg CreateAssetAccountMsg) { + msg.Creator = creator + msg.PubKey = pubkey + return +} + /* Auxiliary functions, could be undocumented */ -func validateAddress(addr crypto.Address) sdk.Error { +func validateAddress(addr sdk.Address) sdk.Error { if addr == nil { return ErrInvalidAddress("address is nil") } - if len(addr) != 20 { + if len(addr) != AddressLength { return ErrInvalidAddress("invalid address length") } return nil diff --git a/types/msgs_test.go b/types/msgs_test.go index f870d46..5c905fd 100644 --- a/types/msgs_test.go +++ b/types/msgs_test.go @@ -258,7 +258,7 @@ func TestCreateAssetAccountMsg_ValidateBasic(t *testing.T) { {"new ICM acc ok", fields{creatorAddress, newPubKey}, sdk.CodeOK}, {"creator is nil", fields{nil, newPubKey}, CodeInvalidAddress}, {"invalid creator len", fields{crypto.Address("short"), newPubKey}, CodeInvalidAddress}, - {"new pubkey is nil", fields{creatorAddress, nil}, CodeInvalidPubKey}, + {"new pubkey is empty", fields{creatorAddress, crypto.PubKey{}}, CodeInvalidPubKey}, {"same creator and acct", fields{newPubKey.Address(), newPubKey}, CodeInvalidPubKey}, } for _, tt := range tests { @@ -334,7 +334,7 @@ func TestCreateAdminMsg_ValidateBasic(t *testing.T) { fields fields want sdk.CodeType }{ - {"nil pubkey", fields{cm: BaseCreateUserMsg{nil, nil}, le: validEntity}, CodeInvalidPubKey}, + {"nil pubkey", fields{cm: BaseCreateUserMsg{nil, crypto.PubKey{}}, le: validEntity}, CodeInvalidPubKey}, {"invalid entity type", fields{cm: validCreateUser, le: BaseLegalEntity{EntityName: "CH", EntityType: "invalid"}}, CodeInvalidEntity}, {"empty entity name", fields{cm: validCreateUser, le: BaseLegalEntity{EntityName: " ", EntityType: EntityClearingHouse}}, CodeInvalidEntity}, {"self create", fields{cm: BaseCreateUserMsg{Creator: pub.Address(), PubKey: pub}, le: validEntity}, CodeSelfCreate}, @@ -460,3 +460,78 @@ func TestMessageTypes(t *testing.T) { assert.Equal(t, freezeOp.Type(), FreezeOperatorType) assert.Equal(t, freezeAd.Type(), FreezeAdminType) } + +func Test_NewCreateAdminMsg(t *testing.T) { + addr := crypto.GenPrivKeyEd25519().PubKey().Address() + pub := crypto.GenPrivKeyEd25519().PubKey() + type args struct { + creator sdk.Address + pubkey crypto.PubKey + entityName string + entityType string + } + tests := []struct { + name string + args args + wantMsg CreateAdminMsg + }{ + {"nil", args{nil, crypto.PubKey{}, "", ""}, CreateAdminMsg{}}, + {"CreateAdminMsg", args{addr, pub, "entityName", "typ"}, CreateAdminMsg{ + BaseCreateUserMsg{PubKey: pub, Creator: addr}, + BaseLegalEntity{EntityName: "entityName", EntityType: "typ"}}}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := NewCreateAdminMsg(tt.args.creator, tt.args.pubkey, tt.args.entityName, tt.args.entityType) + assert.Equal(t, got, tt.wantMsg) + }) + } +} + +func Test_NewCreateOperatorMsg(t *testing.T) { + addr := crypto.GenPrivKeyEd25519().PubKey().Address() + pub := crypto.GenPrivKeyEd25519().PubKey() + type args struct { + creator sdk.Address + pubkey crypto.PubKey + } + tests := []struct { + name string + args args + wantMsg CreateOperatorMsg + }{ + {"nil", args{nil, crypto.PubKey{}}, CreateOperatorMsg{}}, + {"CreateAdminMsg", args{addr, pub}, CreateOperatorMsg{ + BaseCreateUserMsg{PubKey: pub, Creator: addr}, + }}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := NewCreateOperatorMsg(tt.args.creator, tt.args.pubkey) + assert.Equal(t, got, tt.wantMsg) + }) + } +} + +func Test_NewCreateAssetAccountMsg(t *testing.T) { + addr := crypto.GenPrivKeyEd25519().PubKey().Address() + pub := crypto.GenPrivKeyEd25519().PubKey() + type args struct { + creator sdk.Address + pubkey crypto.PubKey + } + tests := []struct { + name string + args args + wantMsg CreateAssetAccountMsg + }{ + {"nil", args{nil, crypto.PubKey{}}, CreateAssetAccountMsg{}}, + {"CreateAdminMsg", args{addr, pub}, CreateAssetAccountMsg{PubKey: pub, Creator: addr}}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := NewCreateAssetAccountMsg(tt.args.creator, tt.args.pubkey) + assert.Equal(t, got, tt.wantMsg) + }) + } +} diff --git a/types/wire.go b/types/wire.go index bd94c2c..acc6e26 100644 --- a/types/wire.go +++ b/types/wire.go @@ -2,39 +2,40 @@ package types import ( sdk "github.com/cosmos/cosmos-sdk/types" - crypto "github.com/tendermint/go-crypto" - wire "github.com/tendermint/go-wire" + "github.com/cosmos/cosmos-sdk/wire" + oldwire "github.com/tendermint/go-wire" ) -var cdc = MakeCodec() +const ( + typeDepositMsg = 0x1 + typeSettleMsg = 0x2 + typeWithdrawMsg = 0x3 + typeCreateAdminMsg = 0x4 + typeCreateOperatorMsg = 0x5 + typeCreateAssetAccountMsg = 0x6 + typeFreezeAdminMsg = 0x7 + typeFreezeOperatorMsg = 0x8 -// RegisterWire is the functions that registers application's -// messages types to a wire.Codec. -func RegisterWire(cdc *wire.Codec) { - cdc.RegisterConcrete(DepositMsg{}, - "com.tendermint.clearchain.DepositMsg", nil) - cdc.RegisterConcrete(SettleMsg{}, - "com.tendermint.clearchain.SettleMsg", nil) - cdc.RegisterConcrete(WithdrawMsg{}, - "com.tendermint.clearchain.WithdrawMsg", nil) - cdc.RegisterConcrete(CreateOperatorMsg{}, - "com.tendermint.clearchain.CreateOperatorMsg", nil) - cdc.RegisterConcrete(CreateAdminMsg{}, - "com.tendermint.clearchain.CreateAdminMsg", nil) - cdc.RegisterConcrete(CreateAssetAccountMsg{}, - "com.tendermint.clearchain.CreateAssetAccountMsg", nil) - cdc.RegisterConcrete(FreezeOperatorMsg{}, - "com.tendermint.clearchain.FreezeOperatorMsg", nil) - cdc.RegisterConcrete(FreezeAdminMsg{}, - "com.tendermint.clearchain.FreezeAdminMsg", nil) -} + typeAppAccount = 0x1 +) // MakeCodec instantiate a wire.Codec and register // all application's types; it returns the new codec. func MakeCodec() *wire.Codec { - cdc := wire.NewCodec() - cdc.RegisterInterface((*sdk.Msg)(nil), nil) - RegisterWire(cdc) // Register types's messages - crypto.RegisterWire(cdc) // Register crypto.[PubKey,PrivKey,Signature] types. - return cdc + var _ = oldwire.RegisterInterface( + struct{ sdk.Msg }{}, + oldwire.ConcreteType{DepositMsg{}, typeDepositMsg}, + oldwire.ConcreteType{SettleMsg{}, typeSettleMsg}, + oldwire.ConcreteType{WithdrawMsg{}, typeWithdrawMsg}, + oldwire.ConcreteType{CreateAdminMsg{}, typeCreateAdminMsg}, + oldwire.ConcreteType{CreateOperatorMsg{}, typeCreateOperatorMsg}, + oldwire.ConcreteType{CreateAssetAccountMsg{}, typeCreateAssetAccountMsg}, + oldwire.ConcreteType{FreezeAdminMsg{}, typeFreezeAdminMsg}, + oldwire.ConcreteType{FreezeOperatorMsg{}, typeFreezeOperatorMsg}, + ) + var _ = oldwire.RegisterInterface( + struct{ sdk.Account }{}, + oldwire.ConcreteType{&AppAccount{}, typeAppAccount}, + ) + return wire.NewCodec() }