Skip to content

Commit

Permalink
Merge pull request cosmos#44 from tendermint/develop
Browse files Browse the repository at this point in the history
v0.2.0
  • Loading branch information
ebuchman authored Mar 6, 2017
2 parents 82c662f + da1f09b commit 6f83510
Show file tree
Hide file tree
Showing 56 changed files with 1,349 additions and 505 deletions.
45 changes: 45 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Changelog

## 0.2.0 (March 6, 2017)

BREAKING CHANGES:

- Update to ABCI v0.4.0 and Tendermint v0.9.0
- Coins are specified on the CLI as `Xcoin`, eg. `5gold`
- `Cost` is now `Fee`

FEATURES:

- CLI for sending transactions and querying the state,
designed to be easily extensible as plugins are implemented
- Run Basecoin in-process with Tendermint
- Add `/account` path in Query
- IBC plugin for InterBlockchain Communication
- Demo script of IBC between two chains

IMPROVEMENTS:

- Use new Tendermint `/commit` endpoint for crafting IBC transactions
- More unit tests
- Use go-crypto S structs and go-data for more standard JSON
- Demo uses fewer sleeps

BUG FIXES:

- Various little fixes in coin arithmetic
- More commit validation in IBC
- Return results from transactions

## PreHistory

##### January 14-18, 2017

- Update to Tendermint v0.8.0
- Cleanup a bit and release blog post

##### September 22, 2016

- Basecoin compiles again



2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ install:
go install github.com/tendermint/basecoin/cmd/...

test:
go test --race `${NOVENDOR}`
go test `${NOVENDOR}`
#go run tests/tendermint/*.go

get_deps:
Expand Down
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ and away you go with a full-stack blockchain and command line tool for transacti

WARNING: Currently uses plain-text private keys for transactions and is otherwise not production ready.

## Prerequisites

* Go to https://golang.org/doc/install to install Golang.
* You will also need to set the $GOPATH environment variable as per the instructions [here](https://golang.org/doc/code.html#GOPATH).

## Installation

On a good day, basecoin can be installed like a normal Go program:
Expand All @@ -21,11 +26,9 @@ On a good day, basecoin can be installed like a normal Go program:
go get -u github.com/tendermint/basecoin/cmd/basecoin
```

In some cases, if that fails, or if another branch is required,
we use `glide` for dependency management.

The guaranteed correct way of compiling from source, assuming you've already
run `go get` or otherwise cloned the repo, is:
If that fails, or if another branch is required, you may have to compile from source.
You will first need to install the Golang package manager [`glide`](https://github.com/Masterminds/glide).

```
cd $GOPATH/src/github.com/tendermint/basecoin
Expand All @@ -41,7 +44,7 @@ This will create the `basecoin` binary in `$GOPATH/bin`.

The basecoin CLI can be used to start a stand-alone basecoin instance (`basecoin start`),
or to start basecoin with Tendermint in the same process (`basecoin start --in-proc`).
It can also be used to send transactions, eg. `basecoin tx send --to 0x4793A333846E5104C46DD9AB9A00E31821B2F301 --amount 100`
It can also be used to send transactions, eg. `basecoin tx send --to 0x4793A333846E5104C46DD9AB9A00E31821B2F301 --amount 100btc,10gold`
See `basecoin --help` and `basecoin [cmd] --help` for more details`.

## Learn more
Expand Down
32 changes: 17 additions & 15 deletions app/app.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package app

import (
"encoding/json"
"strings"

abci "github.com/tendermint/abci/types"
Expand Down Expand Up @@ -51,14 +52,15 @@ func (app *Basecoin) RegisterPlugin(plugin types.Plugin) {
}

// ABCI::SetOption
func (app *Basecoin) SetOption(key string, value string) (log string) {
PluginName, key := splitKey(key)
if PluginName != PluginNameBase {
func (app *Basecoin) SetOption(key string, value string) string {
pluginName, key := splitKey(key)
if pluginName != PluginNameBase {
// Set option on plugin
plugin := app.plugins.GetByName(PluginName)
plugin := app.plugins.GetByName(pluginName)
if plugin == nil {
return "Invalid plugin name: " + PluginName
return "Invalid plugin name: " + pluginName
}
log.Info("SetOption on plugin", "plugin", pluginName, "key", key, "value", value)
return plugin.SetOption(app.state, key, value)
} else {
// Set option on basecoin
Expand All @@ -67,13 +69,13 @@ func (app *Basecoin) SetOption(key string, value string) (log string) {
app.state.SetChainID(value)
return "Success"
case "account":
var err error
var acc *types.Account
wire.ReadJSONPtr(&acc, []byte(value), &err)
var acc types.Account
err := json.Unmarshal([]byte(value), &acc)
if err != nil {
return "Error decoding acc message: " + err.Error()
}
app.state.SetAccount(acc.PubKey.Address(), acc)
app.state.SetAccount(acc.PubKey.Address(), &acc)
log.Info("SetAccount", "addr", acc.PubKey.Address(), "acc", acc)
return "Success"
}
return "Unrecognized option key " + key
Expand Down Expand Up @@ -130,6 +132,12 @@ func (app *Basecoin) Query(reqQuery abci.RequestQuery) (resQuery abci.ResponseQu
return
}

// handle special path for account info
if reqQuery.Path == "/account" {
reqQuery.Path = "/key"
reqQuery.Data = append([]byte("base/a/"), reqQuery.Data...)
}

resQuery, err := app.eyesCli.QuerySync(reqQuery)
if err != nil {
resQuery.Log = "Failed to query MerkleEyes: " + err.Error()
Expand Down Expand Up @@ -188,9 +196,3 @@ func splitKey(key string) (prefix string, suffix string) {
}
return key, ""
}

// (not meant to be called)
// assert that Basecoin implements `abci.BlockchainAware` at compile-time
func _assertABCIBlockchainAware(basecoin *Basecoin) abci.BlockchainAware {
return basecoin
}
35 changes: 14 additions & 21 deletions app/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package app

import (
"encoding/json"
"fmt"
"reflect"

"github.com/pkg/errors"
cmn "github.com/tendermint/go-common"
Expand All @@ -15,9 +13,7 @@ func (app *Basecoin) LoadGenesis(path string) error {
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)
app.SetOption(kv.Key, kv.Value)
}
return nil
}
Expand All @@ -28,7 +24,7 @@ type keyValue struct {
}

func loadGenesis(filePath string) (kvz []keyValue, err error) {
kvz_ := []interface{}{}
kvz_ := []json.RawMessage{}
bytes, err := cmn.ReadFile(filePath)
if err != nil {
return nil, errors.Wrap(err, "loading genesis file")
Expand All @@ -40,24 +36,21 @@ func loadGenesis(filePath string) (kvz []keyValue, err error) {
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))
kv := keyValue{}
rawK := []byte(kvz_[i])
err := json.Unmarshal(rawK, &(kv.Key))
if err != nil {
return nil, errors.Errorf("Non-string key: %s", string(rawK))
}
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)
// convert value to string if possible (otherwise raw json)
rawV := kvz_[i+1]
err = json.Unmarshal(rawV, &(kv.Value))
if err != nil {
kv.Value = string(rawV)
}
kvz = append(kvz, keyValue{key, value})
kvz = append(kvz, kv)
}
return kvz, nil
}
43 changes: 43 additions & 0 deletions app/genesis_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package app

import (
"encoding/hex"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tendermint/go-crypto"
eyescli "github.com/tendermint/merkleeyes/client"
)

func TestLoadGenesis(t *testing.T) {
assert, require := assert.New(t), require.New(t)

eyesCli := eyescli.NewLocalClient("", 0)
app := NewBasecoin(eyesCli)
err := app.LoadGenesis("./testdata/genesis.json")
require.Nil(err, "%+v", err)

// check the chain id
assert.Equal("foo_bar_chain", app.GetState().GetChainID())

// and check the account info - previously calculated values
addr, _ := hex.DecodeString("eb98e0688217cfdeb70eddf4b33cdcc37fc53197")
pkbyte, _ := hex.DecodeString("6880db93598e283a67c4d88fc67a8858aa2de70f713fe94a5109e29c137100c2")

acct := app.GetState().GetAccount(addr)
require.NotNil(acct)

// make sure balance is proper
assert.Equal(2, len(acct.Balance))
assert.EqualValues(12345, acct.Balance[0].Amount)
assert.EqualValues("blank", acct.Balance[0].Denom)

// and public key is parsed properly
apk := acct.PubKey.PubKey
require.NotNil(apk)
epk, ok := apk.(crypto.PubKeyEd25519)
if assert.True(ok) {
assert.EqualValues(pkbyte, epk[:])
}
}
7 changes: 7 additions & 0 deletions app/log.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package app

import (
"github.com/tendermint/go-logger"
)

var log = logger.New("module", "app")
19 changes: 19 additions & 0 deletions app/testdata/genesis.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[
"base/chainID", "foo_bar_chain",
"base/account", {
"pub_key": {
"type": "ed25519",
"data": "6880db93598e283a67c4d88fc67a8858aa2de70f713fe94a5109e29c137100c2"
},
"coins": [
{
"denom": "blank",
"amount": 12345
},
{
"denom": "ETH",
"amount": 654321
}
]
}
]
3 changes: 2 additions & 1 deletion circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ dependencies:
- go get github.com/Masterminds/glide
- go version
- glide --version
- "cd $REPO && glide install"
- "cd $REPO && glide install && go install ./cmd/basecoin"

test:
override:
- "cd $REPO && make test"
- "cd $REPO/demo && bash start.sh"


7 changes: 4 additions & 3 deletions cmd/basecoin/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,22 @@ import (
"os"

"github.com/tendermint/basecoin/cmd/commands"
"github.com/tendermint/basecoin/version"
"github.com/urfave/cli"
)

func main() {
app := cli.NewApp()
app.Name = "basecoin"
app.Usage = "basecoin [command] [args...]"
app.Version = "0.1.0"
app.Version = version.Version
app.Commands = []cli.Command{
commands.StartCmd,
commands.TxCmd,
commands.QueryCmd,
commands.KeyCmd,
commands.VerifyCmd, // TODO: move to merkleeyes?
commands.BlockCmd, // TODO: move to adam?
commands.VerifyCmd,
commands.BlockCmd,
commands.AccountCmd,
}
app.Run(os.Args)
Expand Down
18 changes: 6 additions & 12 deletions cmd/commands/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ var (
Usage: "Destination address for the transaction",
}

AmountFlag = cli.IntFlag{
AmountFlag = cli.StringFlag{
Name: "amount",
Value: 0,
Usage: "Amount of coins to send in the transaction",
Value: "",
Usage: "Coins to send in transaction of the format <amt><coin>,<amt2><coin2>,... (eg: 1btc,2gold,5silver)",
}

FromFlag = cli.StringFlag{
Expand All @@ -66,22 +66,16 @@ var (
Usage: "Sequence number for the account",
}

CoinFlag = cli.StringFlag{
Name: "coin",
Value: "mycoin",
Usage: "Specify a coin denomination",
}

GasFlag = cli.IntFlag{
Name: "gas",
Value: 0,
Usage: "The amount of gas for the transaction",
}

FeeFlag = cli.IntFlag{
FeeFlag = cli.StringFlag{
Name: "fee",
Value: 0,
Usage: "The transaction fee",
Value: "",
Usage: "Coins for the transaction fee of the format <amt><coin>",
}

DataFlag = cli.StringFlag{
Expand Down
Loading

0 comments on commit 6f83510

Please sign in to comment.