diff --git a/Makefile b/Makefile index d22c6561d..42ccfc69c 100644 --- a/Makefile +++ b/Makefile @@ -3,8 +3,11 @@ all: test install NOVENDOR = go list github.com/tendermint/basecoin/... | grep -v /vendor/ - -install: + +build: + go build github.com/tendermint/basecoin/cmd/... + +install: go install github.com/tendermint/basecoin/cmd/... test: @@ -20,4 +23,4 @@ update_deps: get_vendor_deps: go get github.com/Masterminds/glide glide install - + diff --git a/app/app.go b/app/app.go index a2a824814..be618ae72 100644 --- a/app/app.go +++ b/app/app.go @@ -118,12 +118,20 @@ func (app *Basecoin) CheckTx(txBytes []byte) (res abci.Result) { } // TMSP::Query -func (app *Basecoin) Query(query []byte) (res abci.Result) { - if len(query) == 0 { - return abci.ErrEncodingError.SetLog("Query cannot be zero length") +func (app *Basecoin) Query(reqQuery abci.RequestQuery) (resQuery abci.ResponseQuery) { + if len(reqQuery.Data) == 0 { + resQuery.Log = "Query cannot be zero length" + resQuery.Code = abci.CodeType_EncodingError + return } - return app.eyesCli.QuerySync(query) + resQuery, err := app.eyesCli.QuerySync(reqQuery) + if err != nil { + resQuery.Log = "Failed to query MerkleEyes: " + err.Error() + resQuery.Code = abci.CodeType_InternalError + return + } + return } // TMSP::Commit diff --git a/app/genesis.go b/app/genesis.go new file mode 100644 index 000000000..93848c893 --- /dev/null +++ b/app/genesis.go @@ -0,0 +1,63 @@ +package app + +import ( + "encoding/json" + "fmt" + "reflect" + + "github.com/pkg/errors" + cmn "github.com/tendermint/go-common" +) + +func (app *Basecoin) LoadGenesis(path string) error { + kvz, err := loadGenesis(path) + if err != nil { + return err + } + for _, kv := range kvz { + log := app.SetOption(kv.Key, kv.Value) + // TODO: remove debug output + fmt.Printf("Set %v=%v. Log: %v", kv.Key, kv.Value, log) + } + return nil +} + +type keyValue struct { + Key string `json:"key"` + Value string `json:"value"` +} + +func loadGenesis(filePath string) (kvz []keyValue, err error) { + kvz_ := []interface{}{} + bytes, err := cmn.ReadFile(filePath) + if err != nil { + return nil, errors.Wrap(err, "loading genesis file") + } + err = json.Unmarshal(bytes, &kvz_) + if err != nil { + return nil, errors.Wrap(err, "parsing genesis file") + } + if len(kvz_)%2 != 0 { + return nil, errors.New("genesis cannot have an odd number of items. Format = [key1, value1, key2, value2, ...]") + } + for i := 0; i < len(kvz_); i += 2 { + keyIfc := kvz_[i] + valueIfc := kvz_[i+1] + var key, value string + key, ok := keyIfc.(string) + if !ok { + return nil, errors.Errorf("genesis had invalid key %v of type %v", keyIfc, reflect.TypeOf(keyIfc)) + } + if value_, ok := valueIfc.(string); ok { + value = value_ + } else { + valueBytes, err := json.Marshal(valueIfc) + if err != nil { + return nil, errors.Errorf("genesis had invalid value %v: %v", value_, err.Error()) + } + value = string(valueBytes) + } + kvz = append(kvz, keyValue{key, value}) + } + return kvz, nil +} diff --git a/cmd/basecoin/main.go b/cmd/basecoin/main.go index 8d67c2d45..5dc536b91 100644 --- a/cmd/basecoin/main.go +++ b/cmd/basecoin/main.go @@ -1,28 +1,32 @@ package main import ( - "encoding/json" "flag" - "fmt" - "reflect" "github.com/tendermint/abci/server" "github.com/tendermint/basecoin/app" - . "github.com/tendermint/go-common" + cmn "github.com/tendermint/go-common" eyes "github.com/tendermint/merkleeyes/client" ) func main() { - addrPtr := flag.String("address", "tcp://0.0.0.0:46658", "Listen address") eyesPtr := flag.String("eyes", "local", "MerkleEyes address, or 'local' for embedded") + eyesDBNamePtr := flag.String("eyes-db-name", "local.db", "MerkleEyes db name, for embedded") + eyesCacheSizePtr := flag.Int("eyes-cache-size", 10000, "MerkleEyes db cache size, for embedded") genFilePath := flag.String("genesis", "", "Genesis file, if any") flag.Parse() // Connect to MerkleEyes - eyesCli, err := eyes.NewClient(*eyesPtr, "socket") - if err != nil { - Exit("connect to MerkleEyes: " + err.Error()) + var eyesCli *eyes.Client + if *eyesPtr == "local" { + eyesCli = eyes.NewLocalClient(*eyesDBNamePtr, *eyesCacheSizePtr) + } else { + var err error + eyesCli, err = eyes.NewClient(*eyesPtr) + if err != nil { + cmn.Exit("connect to MerkleEyes: " + err.Error()) + } } // Create Basecoin app @@ -30,65 +34,22 @@ func main() { // If genesis file was specified, set key-value options if *genFilePath != "" { - kvz := loadGenesis(*genFilePath) - for _, kv := range kvz { - log := app.SetOption(kv.Key, kv.Value) - fmt.Println(Fmt("Set %v=%v. Log: %v", kv.Key, kv.Value, log)) + err := app.LoadGenesis(*genFilePath) + if err != nil { + cmn.Exit(cmn.Fmt("%+v", err)) } } // Start the listener svr, err := server.NewServer(*addrPtr, "socket", app) if err != nil { - Exit("create listener: " + err.Error()) + cmn.Exit("create listener: " + err.Error()) } // Wait forever - TrapSignal(func() { + cmn.TrapSignal(func() { // Cleanup svr.Stop() }) } - -//---------------------------------------- - -type KeyValue struct { - Key string `json:"key"` - Value string `json:"value"` -} - -func loadGenesis(filePath string) (kvz []KeyValue) { - kvz_ := []interface{}{} - bytes, err := ReadFile(filePath) - if err != nil { - Exit("loading genesis file: " + err.Error()) - } - err = json.Unmarshal(bytes, &kvz_) - if err != nil { - Exit("parsing genesis file: " + err.Error()) - } - if len(kvz_)%2 != 0 { - Exit("genesis cannot have an odd number of items. Format = [key1, value1, key2, value2, ...]") - } - for i := 0; i < len(kvz_); i += 2 { - keyIfc := kvz_[i] - valueIfc := kvz_[i+1] - var key, value string - key, ok := keyIfc.(string) - if !ok { - Exit(Fmt("genesis had invalid key %v of type %v", keyIfc, reflect.TypeOf(keyIfc))) - } - if value_, ok := valueIfc.(string); ok { - value = value_ - } else { - valueBytes, err := json.Marshal(valueIfc) - if err != nil { - Exit(Fmt("genesis had invalid value %v: %v", value_, err.Error())) - } - value = string(valueBytes) - } - kvz = append(kvz, KeyValue{key, value}) - } - return kvz -} diff --git a/cmd/paytovote/main.go b/cmd/paytovote/main.go new file mode 100644 index 000000000..7c7715d99 --- /dev/null +++ b/cmd/paytovote/main.go @@ -0,0 +1,53 @@ +package main + +import ( + "flag" + + "github.com/tendermint/abci/server" + "github.com/tendermint/basecoin/app" + "github.com/tendermint/basecoin/plugins/counter" + cmn "github.com/tendermint/go-common" + eyes "github.com/tendermint/merkleeyes/client" +) + +func main() { + addrPtr := flag.String("address", "tcp://0.0.0.0:46658", "Listen address") + eyesPtr := flag.String("eyes", "local", "MerkleEyes address, or 'local' for embedded") + genFilePath := flag.String("genesis", "", "Genesis file, if any") + flag.Parse() + + // Connect to MerkleEyes + eyesCli, err := eyes.NewClient(*eyesPtr) + if err != nil { + cmn.Exit("connect to MerkleEyes: " + err.Error()) + } + + // Create Basecoin app + app := app.NewBasecoin(eyesCli) + + // add plugins + // TODO: add some more, like the cool voting app + counter := counter.New("counter") + app.RegisterPlugin(counter) + + // If genesis file was specified, set key-value options + if *genFilePath != "" { + err := app.LoadGenesis(*genFilePath) + if err != nil { + cmn.Exit(cmn.Fmt("%+v", err)) + } + } + + // Start the listener + svr, err := server.NewServer(*addrPtr, "socket", app) + if err != nil { + cmn.Exit("create listener: " + err.Error()) + } + + // Wait forever + cmn.TrapSignal(func() { + // Cleanup + svr.Stop() + }) + +} diff --git a/glide.lock b/glide.lock index 6d606a6d6..00754a8ad 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ hash: 3869944d14a8df914ffcad02c2ef3548173daba51c5ea697767f8af77c07b348 -updated: 2017-01-15T14:45:40.368426139-08:00 +updated: 2017-01-28T09:14:54.898268931-08:00 imports: - name: github.com/btcsuite/btcd version: afec1bd1245a4a19e6dfe1306974b733e7cbb9b8 @@ -25,6 +25,8 @@ imports: version: ed8eb9e318d7a84ce5915b495b7d35e0cfe7b5a8 - name: github.com/mattn/go-isatty version: 66b8e73f3f5cda9f96b69efd03dd3d7fc4a5cdb8 +- name: github.com/pkg/errors + version: 248dadf4e9068a0b3e79f02ed0a610d935de5302 - name: github.com/syndtr/goleveldb version: 6ae1797c0b42b9323fc27ff7dcf568df88f2f33d subpackages: @@ -41,7 +43,7 @@ imports: - leveldb/table - leveldb/util - name: github.com/tendermint/abci - version: 05096de3687ac582bec63860b3dd384acd9149aa + version: 8df0bc3a40ccad0d2be10e33c62c404e65c92502 subpackages: - client - server @@ -52,7 +54,7 @@ imports: - edwards25519 - extra25519 - name: github.com/tendermint/go-common - version: 70e694ee76f09058ea38c9ba81b4aa621bd54df1 + version: 339e135776142939d82bc8e699db0bf391fd938d - name: github.com/tendermint/go-config version: e64b424499acd0eb9856b88e10c0dff41628c0d6 - name: github.com/tendermint/go-crypto @@ -68,7 +70,7 @@ imports: - name: github.com/tendermint/go-logger version: cefb3a45c0bf3c493a04e9bcd9b1540528be59f2 - name: github.com/tendermint/go-merkle - version: 2979c7eb8aa020fa1cf203654907dbb889703888 + version: 653cb1f631528351ddbc359b994eb0c96f0341cd - name: github.com/tendermint/go-p2p version: 67c9086b7458eb45b1970483decd01cd744c477a subpackages: @@ -85,12 +87,12 @@ imports: subpackages: - term - name: github.com/tendermint/merkleeyes - version: 2cf87e5f049ab6131aa4ea188c1b5b629d9b3bf9 + version: 00d915af3e425cf57c10afe502fd9e0a6a70acd4 subpackages: - app - client - name: github.com/tendermint/tendermint - version: 9a2dd8bc9279ed2a1a4d4f31cc151f8a621cceb3 + version: 7c15b54cccac574cfe673c473d4edff01c2503ec subpackages: - rpc/core/types - types diff --git a/glide.yaml b/glide.yaml index b3fddf074..ecf4f151b 100644 --- a/glide.yaml +++ b/glide.yaml @@ -18,6 +18,5 @@ import: version: develop - package: github.com/tendermint/abci version: develop - - package: github.com/gorilla/websocket version: v1.1.0 diff --git a/plugins/counter/counter.go b/plugins/counter/counter.go index 61945f20c..5dd42d123 100644 --- a/plugins/counter/counter.go +++ b/plugins/counter/counter.go @@ -32,7 +32,7 @@ func (cp *CounterPlugin) StateKey() []byte { return []byte(fmt.Sprintf("CounterPlugin{name=%v}.State", cp.name)) } -func NewCounterPlugin(name string) *CounterPlugin { +func New(name string) *CounterPlugin { return &CounterPlugin{ name: name, } @@ -43,7 +43,6 @@ func (cp *CounterPlugin) SetOption(store types.KVStore, key string, value string } func (cp *CounterPlugin) RunTx(store types.KVStore, ctx types.CallContext, txBytes []byte) (res abci.Result) { - // Decode tx var tx CounterTx err := wire.ReadBinaryBytes(txBytes, &tx) diff --git a/plugins/counter/counter_test.go b/plugins/counter/counter_test.go index b9aa88946..7f07b4d31 100644 --- a/plugins/counter/counter_test.go +++ b/plugins/counter/counter_test.go @@ -15,7 +15,7 @@ import ( func TestCounterPlugin(t *testing.T) { // Basecoin initialization - eyesCli := eyescli.NewLocalClient() + eyesCli := eyescli.NewLocalClient("", 0) chainID := "test_chain_id" bcApp := app.NewBasecoin(eyesCli) bcApp.SetOption("base/chainID", chainID) @@ -23,7 +23,7 @@ func TestCounterPlugin(t *testing.T) { // Add Counter plugin counterPluginName := "testcounter" - counterPlugin := NewCounterPlugin(counterPluginName) + counterPlugin := New(counterPluginName) bcApp.RegisterPlugin(counterPlugin) // Account initialization diff --git a/tests/tmsp/tmsp_test.go b/tests/tmsp/tmsp_test.go index a6a03686a..c00cadedb 100644 --- a/tests/tmsp/tmsp_test.go +++ b/tests/tmsp/tmsp_test.go @@ -12,7 +12,7 @@ import ( ) func TestSendTx(t *testing.T) { - eyesCli := eyescli.NewLocalClient() + eyesCli := eyescli.NewLocalClient("", 0) chainID := "test_chain_id" bcApp := app.NewBasecoin(eyesCli) bcApp.SetOption("base/chainID", chainID) @@ -58,7 +58,7 @@ func TestSendTx(t *testing.T) { } func TestSequence(t *testing.T) { - eyesCli := eyescli.NewLocalClient() + eyesCli := eyescli.NewLocalClient("", 0) chainID := "test_chain_id" bcApp := app.NewBasecoin(eyesCli) bcApp.SetOption("base/chainID", chainID)