Merge pull request #6 from rigelrozanski/voteplugin
Test plugin integration and testing
This commit is contained in:
commit
0f90f51262
2
Makefile
2
Makefile
|
@ -9,7 +9,7 @@ install:
|
|||
|
||||
test:
|
||||
go test --race `${NOVENDOR}`
|
||||
go run tests/tmsp/*.go
|
||||
#go run tests/tendermint/*.go
|
||||
|
||||
get_deps:
|
||||
go get -d github.com/tendermint/basecoin/...
|
||||
|
|
|
@ -17,9 +17,11 @@ const (
|
|||
|
||||
PluginTypeByteBase = 0x01
|
||||
PluginTypeByteEyes = 0x02
|
||||
PluginTypeByteVote = 0x03
|
||||
|
||||
PluginNameBase = "base"
|
||||
PluginNameEyes = "eyes"
|
||||
PluginNameVote = "vote"
|
||||
)
|
||||
|
||||
type Basecoin struct {
|
||||
|
@ -45,6 +47,10 @@ func (app *Basecoin) Info() string {
|
|||
return Fmt("Basecoin v%v", version)
|
||||
}
|
||||
|
||||
func (app *Basecoin) RegisterPlugin(typeByte byte, name string, plugin types.Plugin) {
|
||||
app.plugins.RegisterPlugin(typeByte, name, plugin)
|
||||
}
|
||||
|
||||
// TMSP::SetOption
|
||||
func (app *Basecoin) SetOption(key string, value string) (log string) {
|
||||
PluginName, key := splitKey(key)
|
||||
|
|
|
@ -1,36 +1,29 @@
|
|||
package main
|
||||
package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/tendermint/basecoin/app"
|
||||
"github.com/tendermint/basecoin/tests"
|
||||
cmn "github.com/tendermint/basecoin/common"
|
||||
"github.com/tendermint/basecoin/types"
|
||||
. "github.com/tendermint/go-common"
|
||||
"github.com/tendermint/go-crypto"
|
||||
"github.com/tendermint/go-wire"
|
||||
eyescli "github.com/tendermint/merkleeyes/client"
|
||||
)
|
||||
|
||||
func main() {
|
||||
testSendTx()
|
||||
testSequence()
|
||||
}
|
||||
|
||||
func testSendTx() {
|
||||
func TestSendTx(t *testing.T) {
|
||||
eyesCli := eyescli.NewLocalClient()
|
||||
chainID := "test_chain_id"
|
||||
bcApp := app.NewBasecoin(eyesCli)
|
||||
bcApp := NewBasecoin(eyesCli)
|
||||
bcApp.SetOption("base/chainID", chainID)
|
||||
fmt.Println(bcApp.Info())
|
||||
t.Log(bcApp.Info())
|
||||
|
||||
test1PrivAcc := tests.PrivAccountFromSecret("test1")
|
||||
test2PrivAcc := tests.PrivAccountFromSecret("test2")
|
||||
test1PrivAcc := cmn.PrivAccountFromSecret("test1")
|
||||
test2PrivAcc := cmn.PrivAccountFromSecret("test2")
|
||||
|
||||
// Seed Basecoin with account
|
||||
test1Acc := test1PrivAcc.Account
|
||||
test1Acc.Balance = types.Coins{{"", 1000}}
|
||||
fmt.Println(bcApp.SetOption("base/account", string(wire.JSONBytes(test1Acc))))
|
||||
t.Log(bcApp.SetOption("base/account", string(wire.JSONBytes(test1Acc))))
|
||||
|
||||
res := bcApp.Commit()
|
||||
if res.IsErr() {
|
||||
|
@ -42,7 +35,7 @@ func testSendTx() {
|
|||
Fee: 0,
|
||||
Gas: 0,
|
||||
Inputs: []types.TxInput{
|
||||
makeInput(test1PrivAcc.Account.PubKey, types.Coins{{"", 1}}, 1),
|
||||
cmn.MakeInput(test1PrivAcc.Account.PubKey, types.Coins{{"", 1}}, 1),
|
||||
},
|
||||
Outputs: []types.TxOutput{
|
||||
types.TxOutput{
|
||||
|
@ -54,42 +47,41 @@ func testSendTx() {
|
|||
|
||||
// Sign request
|
||||
signBytes := tx.SignBytes(chainID)
|
||||
fmt.Printf("Sign bytes: %X\n", signBytes)
|
||||
t.Log("Sign bytes: %X\n", signBytes)
|
||||
sig := test1PrivAcc.PrivKey.Sign(signBytes)
|
||||
tx.Inputs[0].Signature = sig
|
||||
//fmt.Println("tx:", tx)
|
||||
fmt.Printf("Signed TX bytes: %X\n", wire.BinaryBytes(struct{ types.Tx }{tx}))
|
||||
t.Log("Signed TX bytes: %X\n", wire.BinaryBytes(struct{ types.Tx }{tx}))
|
||||
|
||||
// Write request
|
||||
txBytes := wire.BinaryBytes(struct{ types.Tx }{tx})
|
||||
res = bcApp.AppendTx(txBytes)
|
||||
fmt.Println(res)
|
||||
t.Log(res)
|
||||
if res.IsErr() {
|
||||
Exit(Fmt("Failed: %v", res.Error()))
|
||||
t.Errorf(Fmt("Failed: %v", res.Error()))
|
||||
}
|
||||
}
|
||||
|
||||
func testSequence() {
|
||||
func TestSequence(t *testing.T) {
|
||||
eyesCli := eyescli.NewLocalClient()
|
||||
chainID := "test_chain_id"
|
||||
bcApp := app.NewBasecoin(eyesCli)
|
||||
bcApp := NewBasecoin(eyesCli)
|
||||
bcApp.SetOption("base/chainID", chainID)
|
||||
fmt.Println(bcApp.Info())
|
||||
t.Log(bcApp.Info())
|
||||
|
||||
// Get the test account
|
||||
test1PrivAcc := tests.PrivAccountFromSecret("test1")
|
||||
test1PrivAcc := cmn.PrivAccountFromSecret("test1")
|
||||
test1Acc := test1PrivAcc.Account
|
||||
test1Acc.Balance = types.Coins{{"", 1 << 53}}
|
||||
fmt.Println(bcApp.SetOption("base/account", string(wire.JSONBytes(test1Acc))))
|
||||
t.Log(bcApp.SetOption("base/account", string(wire.JSONBytes(test1Acc))))
|
||||
|
||||
res := bcApp.Commit()
|
||||
if res.IsErr() {
|
||||
Exit(Fmt("Failed Commit: %v", res.Error()))
|
||||
t.Errorf(Fmt("Failed Commit: %v", res.Error()))
|
||||
}
|
||||
|
||||
sequence := int(1)
|
||||
// Make a bunch of PrivAccounts
|
||||
privAccounts := tests.RandAccounts(1000, 1000000, 0)
|
||||
privAccounts := cmn.RandAccounts(1000, 1000000, 0)
|
||||
privAccountSequences := make(map[string]int)
|
||||
// Send coins to each account
|
||||
|
||||
|
@ -100,7 +92,7 @@ func testSequence() {
|
|||
Fee: 2,
|
||||
Gas: 2,
|
||||
Inputs: []types.TxInput{
|
||||
makeInput(test1Acc.PubKey, types.Coins{{"", 1000002}}, sequence),
|
||||
cmn.MakeInput(test1Acc.PubKey, types.Coins{{"", 1000002}}, sequence),
|
||||
},
|
||||
Outputs: []types.TxOutput{
|
||||
types.TxOutput{
|
||||
|
@ -115,22 +107,22 @@ func testSequence() {
|
|||
signBytes := tx.SignBytes(chainID)
|
||||
sig := test1PrivAcc.PrivKey.Sign(signBytes)
|
||||
tx.Inputs[0].Signature = sig
|
||||
// fmt.Printf("ADDR: %X -> %X\n", tx.Inputs[0].Address, tx.Outputs[0].Address)
|
||||
// t.Log("ADDR: %X -> %X\n", tx.Inputs[0].Address, tx.Outputs[0].Address)
|
||||
|
||||
// Write request
|
||||
txBytes := wire.BinaryBytes(struct{ types.Tx }{tx})
|
||||
res := bcApp.AppendTx(txBytes)
|
||||
if res.IsErr() {
|
||||
Exit("AppendTx error: " + res.Error())
|
||||
t.Errorf("AppendTx error: " + res.Error())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fmt.Println("-------------------- RANDOM SENDS --------------------")
|
||||
t.Log("-------------------- RANDOM SENDS --------------------")
|
||||
|
||||
res = bcApp.Commit()
|
||||
if res.IsErr() {
|
||||
Exit(Fmt("Failed Commit: %v", res.Error()))
|
||||
t.Errorf(Fmt("Failed Commit: %v", res.Error()))
|
||||
}
|
||||
|
||||
// Now send coins between these accounts
|
||||
|
@ -150,7 +142,7 @@ func testSequence() {
|
|||
Fee: 2,
|
||||
Gas: 2,
|
||||
Inputs: []types.TxInput{
|
||||
makeInput(privAccountA.Account.PubKey, types.Coins{{"", 3}}, privAccountASequence+1),
|
||||
cmn.MakeInput(privAccountA.Account.PubKey, types.Coins{{"", 3}}, privAccountASequence+1),
|
||||
},
|
||||
Outputs: []types.TxOutput{
|
||||
types.TxOutput{
|
||||
|
@ -164,26 +156,13 @@ func testSequence() {
|
|||
signBytes := tx.SignBytes(chainID)
|
||||
sig := privAccountA.PrivKey.Sign(signBytes)
|
||||
tx.Inputs[0].Signature = sig
|
||||
// fmt.Printf("ADDR: %X -> %X\n", tx.Inputs[0].Address, tx.Outputs[0].Address)
|
||||
// t.Log("ADDR: %X -> %X\n", tx.Inputs[0].Address, tx.Outputs[0].Address)
|
||||
|
||||
// Write request
|
||||
txBytes := wire.BinaryBytes(struct{ types.Tx }{tx})
|
||||
res := bcApp.AppendTx(txBytes)
|
||||
if res.IsErr() {
|
||||
Exit("AppendTx error: " + res.Error())
|
||||
t.Errorf("AppendTx error: " + res.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func makeInput(pubKey crypto.PubKey, coins types.Coins, sequence int) types.TxInput {
|
||||
input := types.TxInput{
|
||||
Address: pubKey.Address(),
|
||||
PubKey: pubKey,
|
||||
Coins: coins,
|
||||
Sequence: sequence,
|
||||
}
|
||||
if sequence > 1 {
|
||||
input.PubKey = nil
|
||||
}
|
||||
return input
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
package tests
|
||||
//functions used in testing throughout
|
||||
package common
|
||||
|
||||
import (
|
||||
"github.com/tendermint/basecoin/types"
|
||||
|
@ -44,3 +45,17 @@ func RandAccounts(num int, minAmount int64, maxAmount int64) []types.PrivAccount
|
|||
|
||||
return privAccs
|
||||
}
|
||||
|
||||
//make input term for the AppTx or SendTx Types
|
||||
func MakeInput(pubKey crypto.PubKey, coins types.Coins, sequence int) types.TxInput {
|
||||
input := types.TxInput{
|
||||
Address: pubKey.Address(),
|
||||
PubKey: pubKey,
|
||||
Coins: coins,
|
||||
Sequence: sequence,
|
||||
}
|
||||
if sequence > 1 {
|
||||
input.PubKey = nil
|
||||
}
|
||||
return input
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
package vote
|
||||
|
||||
import (
|
||||
"github.com/tendermint/basecoin/types"
|
||||
"github.com/tendermint/go-wire"
|
||||
tmsp "github.com/tendermint/tmsp/types"
|
||||
)
|
||||
|
||||
type Vote struct {
|
||||
bb *ballotBox
|
||||
}
|
||||
|
||||
type ballotBox struct {
|
||||
issue string
|
||||
votesYes int
|
||||
votesNo int
|
||||
}
|
||||
|
||||
type Tx struct {
|
||||
voteYes bool
|
||||
}
|
||||
|
||||
func NewVoteInstance(issue string) Vote {
|
||||
return Vote{
|
||||
&ballotBox{
|
||||
issue: issue,
|
||||
votesYes: 0,
|
||||
votesNo: 0,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (app Vote) SetOption(store types.KVStore, key string, value string) (log string) {
|
||||
return ""
|
||||
}
|
||||
|
||||
//because no coins are being exchanged ctx is unused
|
||||
func (app Vote) RunTx(store types.KVStore, ctx types.CallContext, txBytes []byte) (res tmsp.Result) {
|
||||
|
||||
// Decode tx
|
||||
var tx Tx
|
||||
err := wire.ReadBinaryBytes(txBytes, &tx)
|
||||
if err != nil {
|
||||
return tmsp.ErrBaseEncodingError.AppendLog("Error decoding tx: " + err.Error())
|
||||
}
|
||||
|
||||
//Read the ballotBox from the store
|
||||
kvBytes := store.Get([]byte(app.bb.issue))
|
||||
var tempBB ballotBox
|
||||
|
||||
//does the issue already exist?
|
||||
if kvBytes != nil {
|
||||
err := wire.ReadBinaryBytes(kvBytes, &tempBB)
|
||||
if err != nil {
|
||||
return tmsp.ErrBaseEncodingError.AppendLog("Error decoding BallotBox: " + err.Error())
|
||||
}
|
||||
} else {
|
||||
|
||||
//TODO add extra fee for opening new issue
|
||||
|
||||
tempBB = ballotBox{
|
||||
issue: app.bb.issue,
|
||||
votesYes: 0,
|
||||
votesNo: 0,
|
||||
}
|
||||
issueBytes := wire.BinaryBytes(struct{ ballotBox }{tempBB})
|
||||
store.Set([]byte(app.bb.issue), issueBytes)
|
||||
}
|
||||
|
||||
//Write the updated ballotBox to the store
|
||||
if tx.voteYes {
|
||||
tempBB.votesYes += 1
|
||||
} else {
|
||||
tempBB.votesNo += 1
|
||||
}
|
||||
issueBytes := wire.BinaryBytes(struct{ ballotBox }{tempBB})
|
||||
store.Set([]byte(app.bb.issue), issueBytes)
|
||||
|
||||
return tmsp.OK
|
||||
}
|
||||
|
||||
//unused
|
||||
func (app Vote) InitChain(store types.KVStore, vals []*tmsp.Validator) {
|
||||
}
|
||||
|
||||
func (app Vote) BeginBlock(store types.KVStore, height uint64) {
|
||||
}
|
||||
|
||||
func (app Vote) EndBlock(store types.KVStore, height uint64) []*tmsp.Validator {
|
||||
var diffs []*tmsp.Validator
|
||||
return diffs
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
package vote
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/tendermint/basecoin/app"
|
||||
cmn "github.com/tendermint/basecoin/common"
|
||||
"github.com/tendermint/basecoin/types"
|
||||
. "github.com/tendermint/go-common"
|
||||
"github.com/tendermint/go-wire"
|
||||
eyescli "github.com/tendermint/merkleeyes/client"
|
||||
)
|
||||
|
||||
func TestVote(t *testing.T) {
|
||||
//base initialization
|
||||
eyesCli := eyescli.NewLocalClient()
|
||||
chainID := "test_chain_id"
|
||||
bcApp := app.NewBasecoin(eyesCli)
|
||||
bcApp.SetOption("base/chainID", chainID)
|
||||
fmt.Println(bcApp.Info())
|
||||
|
||||
//account initialization
|
||||
test1PrivAcc := cmn.PrivAccountFromSecret("test1")
|
||||
|
||||
// Seed Basecoin with account
|
||||
test1Acc := test1PrivAcc.Account
|
||||
test1Acc.Balance = types.Coins{{"", 1000}}
|
||||
fmt.Println(bcApp.SetOption("base/account", string(wire.JSONBytes(test1Acc))))
|
||||
|
||||
//vote initialization
|
||||
votePlugin := NewVoteInstance("humanRights")
|
||||
var typeByte byte = app.PluginTypeByteVote
|
||||
bcApp.RegisterPlugin(
|
||||
typeByte,
|
||||
app.PluginNameVote,
|
||||
votePlugin,
|
||||
)
|
||||
|
||||
//commit
|
||||
res := bcApp.Commit()
|
||||
if res.IsErr() {
|
||||
Exit(Fmt("Failed Commit: %v", res.Error()))
|
||||
}
|
||||
|
||||
//transaction sequence number
|
||||
seqNum := 1
|
||||
|
||||
//Construct, Sign, Write function variable
|
||||
CSW := func(fees, sendCoins int64) {
|
||||
// Construct an AppTx signature
|
||||
tx := &types.AppTx{
|
||||
Fee: fees,
|
||||
Gas: 0,
|
||||
Type: typeByte,
|
||||
Input: cmn.MakeInput(test1Acc.PubKey, types.Coins{{"", sendCoins}}, seqNum),
|
||||
Data: wire.BinaryBytes(struct{ Tx }{Tx{voteYes: true}}), //a vote for human rights
|
||||
}
|
||||
|
||||
// Sign request
|
||||
signBytes := tx.SignBytes(chainID)
|
||||
fmt.Printf("Sign bytes: %X\n", signBytes)
|
||||
sig := test1PrivAcc.PrivKey.Sign(signBytes)
|
||||
tx.Input.Signature = sig
|
||||
fmt.Printf("Signed TX bytes: %X\n", wire.BinaryBytes(struct{ types.Tx }{tx}))
|
||||
|
||||
// Write request
|
||||
txBytes := wire.BinaryBytes(struct{ types.Tx }{tx})
|
||||
res = bcApp.AppendTx(txBytes)
|
||||
fmt.Println(res)
|
||||
|
||||
if res.IsOK() {
|
||||
seqNum += 1
|
||||
}
|
||||
}
|
||||
|
||||
//Test a basic send, no fees
|
||||
CSW(0, 1)
|
||||
if res.IsErr() {
|
||||
Exit(Fmt("Failed: %v", res.Error()))
|
||||
}
|
||||
|
||||
//Test fee prevented transaction
|
||||
CSW(2, 1)
|
||||
if res.IsOK() {
|
||||
Exit(Fmt("expected bad transaction"))
|
||||
}
|
||||
|
||||
//Test equal fees
|
||||
CSW(2, 2)
|
||||
if res.IsErr() {
|
||||
Exit(Fmt("Failed: %v", res.Error()))
|
||||
}
|
||||
|
||||
//Test more send coins than fees
|
||||
CSW(2, 3)
|
||||
if res.IsErr() {
|
||||
Exit(Fmt("Failed: %v", res.Error()))
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/tendermint/basecoin/tests"
|
||||
cmn "github.com/tendermint/basecoin/common"
|
||||
"github.com/tendermint/basecoin/types"
|
||||
. "github.com/tendermint/go-common"
|
||||
"github.com/tendermint/go-rpc/client"
|
||||
|
@ -37,10 +37,10 @@ func main() {
|
|||
}()
|
||||
|
||||
// Get the root account
|
||||
root := tests.PrivAccountFromSecret("test")
|
||||
root := cmn.PrivAccountFromSecret("test")
|
||||
sequence := int(0)
|
||||
// Make a bunch of PrivAccounts
|
||||
privAccounts := tests.RandAccounts(1000, 1000000, 0)
|
||||
privAccounts := cmn.RandAccounts(1000, 1000000, 0)
|
||||
privAccountSequences := make(map[string]int)
|
||||
|
||||
// Send coins to each account
|
||||
|
|
Loading…
Reference in New Issue