Skip to content

Commit

Permalink
added return coins
Browse files Browse the repository at this point in the history
interim
  • Loading branch information
rigelrozanski committed Feb 2, 2017
1 parent d48a960 commit 2930f51
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 32 deletions.
3 changes: 1 addition & 2 deletions cmd/paytovote/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package main

import (
"flag"
"path"

"github.com/tendermint/abci/server"
"github.com/tendermint/basecoin/app"
Expand All @@ -18,7 +17,7 @@ func main() {
flag.Parse()

// Connect to MerkleEyes
eyesCli := eyes.NewLocalClient(path.Join(".", "merkleeyes.db"), 0)
eyesCli := eyes.NewLocalClient("", 0) //non-persistent instance of merkleeyes

// Create Basecoin app
app := app.NewBasecoin(eyesCli)
Expand Down
55 changes: 43 additions & 12 deletions plugins/paytovote/paytovote.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"

abci "github.com/tendermint/abci/types"
"github.com/tendermint/basecoin/state"
"github.com/tendermint/basecoin/types"
"github.com/tendermint/go-wire"
)
Expand Down Expand Up @@ -98,7 +99,12 @@ func (p2v *P2VPlugin) SetOption(store types.KVStore, key string, value string) (
func (p2v *P2VPlugin) RunTx(store types.KVStore, ctx types.CallContext, txBytes []byte) (res abci.Result) {

defer func() {
//TODO return the ctx coins to the wallet if there is an error
//Return the ctx coins to the wallet if there is an error
if res.IsErr() {
acc := ctx.CallerAccount
acc.Balance = acc.Balance.Plus(ctx.Coins) // add the context transaction coins
state.SetAccount(store, ctx.CallerAddress, acc) // save the new balance
}
}()

//Determine the transaction type and then send to the appropriate transaction function
Expand All @@ -117,15 +123,43 @@ func (p2v *P2VPlugin) RunTx(store types.KVStore, ctx types.CallContext, txBytes
}
}

func chargeFee(ctx types.CallContext, fee types.Coins) {
func chargeFee(store types.KVStore, ctx types.CallContext, fee types.Coins) {

//Charge the Fee from the context coins
leftoverCoins := ctx.Coins.Minus(fee)
if !leftoverCoins.IsZero() {
// TODO If there are any funds left over, return funds.
// ctx.CallerAccount is synced w/ store, so just modify that and store it.
lc := "leftoverCoins: "
for i := 0; i < len(leftoverCoins); i++ {
lc += " " + leftoverCoins[i].String()
}
fmt.Println(lc)
lc = "fee: "
for i := 0; i < len(fee); i++ {
lc += " " + fee[i].String()
}
fmt.Println(lc)

acc := ctx.CallerAccount
lc = "acc b4: "
for i := 0; i < len(acc.Balance); i++ {
lc += " " + acc.Balance[i].String()
}
fmt.Println(lc)

//return leftover coins
acc.Balance = acc.Balance.Plus(leftoverCoins) // subtract fees
state.SetAccount(store, ctx.CallerAddress, acc) // save the new balance
lc = "acc aftr: "
for i := 0; i < len(acc.Balance); i++ {
lc += " " + acc.Balance[i].String()
}
fmt.Println(lc)

}
}

func (p2v *P2VPlugin) runTxCreateIssue(store types.KVStore, ctx types.CallContext, txBytes []byte) (res abci.Result) {

// Decode tx
var tx createIssueTx
err := wire.ReadBinaryBytes(txBytes, &tx)
Expand Down Expand Up @@ -161,11 +195,12 @@ func (p2v *P2VPlugin) runTxCreateIssue(store types.KVStore, ctx types.CallContex
// Create and Save P2VIssue, charge fee, return
newP2VIssue := newP2VIssue(tx.Issue, tx.FeePerVote)
store.Set(p2v.IssueKey(tx.Issue), wire.BinaryBytes(newP2VIssue))
chargeFee(ctx, tx.Fee2CreateIssue)
chargeFee(store, ctx, tx.Fee2CreateIssue)
return abci.NewResultOK(wire.BinaryBytes(p2vIssue), "")
}

func (p2v *P2VPlugin) runTxVote(store types.KVStore, ctx types.CallContext, txBytes []byte) (res abci.Result) {

// Decode tx
var tx voteTx
err := wire.ReadBinaryBytes(txBytes, &tx)
Expand Down Expand Up @@ -209,16 +244,12 @@ func (p2v *P2VPlugin) runTxVote(store types.KVStore, ctx types.CallContext, txBy

// Save P2VIssue, charge fee, return
store.Set(p2v.IssueKey(tx.Issue), wire.BinaryBytes(p2vIssue))
chargeFee(ctx, p2vIssue.FeePerVote)
chargeFee(store, ctx, p2vIssue.FeePerVote)
return abci.NewResultOK(wire.BinaryBytes(p2vIssue), "")
}

func (p2v *P2VPlugin) InitChain(store types.KVStore, vals []*abci.Validator) {
}

func (p2v *P2VPlugin) BeginBlock(store types.KVStore, height uint64) {
}

func (p2v *P2VPlugin) InitChain(store types.KVStore, vals []*abci.Validator) {}
func (p2v *P2VPlugin) BeginBlock(store types.KVStore, height uint64) {}
func (p2v *P2VPlugin) EndBlock(store types.KVStore, height uint64) []*abci.Validator {
return nil
}
49 changes: 31 additions & 18 deletions plugins/paytovote/paytovote_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package paytovote

import (
"path"
"testing"

"github.com/stretchr/testify/assert"
abci "github.com/tendermint/abci/types"
"github.com/tendermint/basecoin/app"
"github.com/tendermint/basecoin/state"
"github.com/tendermint/basecoin/testutils"
"github.com/tendermint/basecoin/types"
"github.com/tendermint/go-wire"
Expand All @@ -16,22 +16,22 @@ import (
func TestP2VPlugin(t *testing.T) {

// Basecoin initialization
eyesCli := eyescli.NewLocalClient(path.Join(".", "merkleeyes.db"), 0)
eyesClient := eyescli.NewLocalClient("", 0) //non-persistent instance of merkleeyes
chainID := "test_chain_id"
bcApp := app.NewBasecoin(eyesCli)
bcApp := app.NewBasecoin(store)
bcApp.SetOption("base/chainID", chainID)
t.Log(bcApp.Info())

// Add Counter plugin
P2VPlugin := New()
bcApp.RegisterPlugin(P2VPlugin)

// Account initialization
test1PrivAcc := testutils.PrivAccountFromSecret("test1")
test1Acc := test1PrivAcc.Account

// Seed Basecoin with account
test1Acc := test1PrivAcc.Account
test1Acc.Balance = types.Coins{{"", 1000}, {"issueToken", 1000}, {"voteToken", 1000}}
startBal := types.Coins{{"", 1000}, {"issueToken", 1000}, {"voteToken", 1000}}
test1Acc.Balance = startBal
bcApp.SetOption("base/account", string(wire.JSONBytes(test1Acc)))

deliverTx := func(gas int64,
Expand All @@ -51,27 +51,33 @@ func TestP2VPlugin(t *testing.T) {

// Sign request
signBytes := tx.SignBytes(chainID)
t.Logf("Sign bytes: %X\n", signBytes)
sig := test1PrivAcc.PrivKey.Sign(signBytes)
tx.Input.Signature = sig
t.Logf("Signed TX bytes: %X\n", wire.BinaryBytes(struct{ types.Tx }{tx}))

// Write request
txBytes := wire.BinaryBytes(struct{ types.Tx }{tx})
return bcApp.DeliverTx(txBytes)
}

testBalance := func(expected types.Coins) {
//TODO debug testBalance (acc returns nil, bad store?)
/*acc := state.GetAccount(store, test1Acc.PubKey.Address())
bal := acc.Balance
if !bal.IsEqual(expected) {
var expStr, balStr string
for i := 0; i < len(expected); i++ {
expStr += " " + expected[i].String()
}
for i := 0; i < len(bal); i++ {
balStr += " " + bal[i].String()
}
t.Errorf("bad balance expected %v, got %v", expStr, balStr)
}*/
}

//TODO: Generate tests which query the results of an issue
/* queryIssue := func(issue string) abci.Result {
key := P2VPlugin.StateKey(issue)
query := make([]byte, 1+wire.ByteSliceSize(key))
buf := query
buf[0] = 0x01 // Get TypeByte
buf = buf[1:]
wire.PutByteSlice(buf, key)
t.Log(len(query))
return bcApp.Query(query)
}*/
//
// REF: deliverTx(gas, fee, inputCoins, inputSequence, NewVoteTxBytes(issue, voteTypeByte))
// REF: deliverTx(gas, fee, inputCoins, inputSequence, NewCreateIssueTxBytes(issue, feePerVote, fee2CreateIssue))

Expand All @@ -82,33 +88,40 @@ func TestP2VPlugin(t *testing.T) {
res := deliverTx(0, types.Coin{}, types.Coins{{"", 1}, {"issueToken", 1}, {"voteToken", 2}}, 1,
NewCreateIssueTxBytes(issue1, types.Coins{{"voteToken", 2}}, types.Coins{{"issueToken", 1}}))
assert.True(t, res.IsOK(), res.String())
testBalance(startBal.Minus(types.Coins{{"issueToken", 1}}))

// Test a basic votes
res = deliverTx(0, types.Coin{}, types.Coins{{"", 1}, {"issueToken", 1}, {"voteToken", 2}}, 2,
NewVoteTxBytes(issue1, TypeByteVoteFor))
assert.True(t, res.IsOK(), res.String())
testBalance(startBal.Minus(types.Coins{{"issueToken", 1}, {"voteToken", 2}}))

res = deliverTx(0, types.Coin{}, types.Coins{{"", 1}, {"issueToken", 1}, {"voteToken", 2}}, 3,
NewVoteTxBytes(issue1, TypeByteVoteAgainst))
assert.True(t, res.IsOK(), res.String())
testBalance(startBal.Minus(types.Coins{{"issueToken", 1}, {"voteToken", 4}}))

// Test prevented voting on non-existent issue
res = deliverTx(0, types.Coin{}, types.Coins{{"", 1}, {"issueToken", 1}, {"voteToken", 2}}, 5,
NewVoteTxBytes(issue2, TypeByteVoteFor))
assert.True(t, res.IsErr(), res.String())
testBalance(startBal.Minus(types.Coins{{"issueToken", 1}, {"voteToken", 4}}))

// Test prevented duplicate issue generation
res = deliverTx(0, types.Coin{}, types.Coins{{"", 1}, {"issueToken", 1}, {"voteToken", 2}}, 5,
NewCreateIssueTxBytes(issue1, types.Coins{{"voteToken", 1}}, types.Coins{{"issueToken", 1}}))
assert.True(t, res.IsErr(), res.String())
testBalance(startBal.Minus(types.Coins{{"issueToken", 1}, {"voteToken", 4}}))

// Test prevented issue generation from insufficient funds
res = deliverTx(0, types.Coin{}, types.Coins{{"", 1}, {"issueToken", 1}, {"voteToken", 2}}, 5,
NewCreateIssueTxBytes(issue2, types.Coins{{"voteToken", 1}}, types.Coins{{"issueToken", 2}}))
assert.True(t, res.IsErr(), res.String())
testBalance(startBal.Minus(types.Coins{{"issueToken", 1}, {"voteToken", 4}}))

// Test prevented voting from insufficient funds
res = deliverTx(0, types.Coin{}, types.Coins{{"", 1}, {"issueToken", 1}, {"voteToken", 1}}, 5,
NewVoteTxBytes(issue1, TypeByteVoteFor))
assert.True(t, res.IsErr(), res.String())
testBalance(startBal.Minus(types.Coins{{"issueToken", 1}, {"voteToken", 4}}))
}

0 comments on commit 2930f51

Please sign in to comment.