Got counter tx working, needs testing
This commit is contained in:
parent
66ec2f266c
commit
8f67b6be84
@ -57,3 +57,42 @@ func (s *AppTx) TxBytes() ([]byte, error) {
|
||||
txBytes := wire.BinaryBytes(bc.TxS{s.Tx})
|
||||
return txBytes, nil
|
||||
}
|
||||
|
||||
// AddSigner sets address and pubkey info on the tx based on the key that
|
||||
// will be used for signing
|
||||
func (a *AppTx) AddSigner(pk crypto.PubKey) {
|
||||
// get addr if available
|
||||
var addr []byte
|
||||
if !pk.Empty() {
|
||||
addr = pk.Address()
|
||||
}
|
||||
|
||||
// set the send address, and pubkey if needed
|
||||
in := &a.Tx.Input
|
||||
in.Address = addr
|
||||
if in.Sequence == 1 {
|
||||
in.PubKey = pk
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: this should really be in the basecoin.types SendTx,
|
||||
// but that code is too ugly now, needs refactor..
|
||||
func (a *AppTx) ValidateBasic() error {
|
||||
if a.chainID == "" {
|
||||
return errors.New("No chainId specified")
|
||||
}
|
||||
in := a.Tx.Input
|
||||
if len(in.Address) != 20 {
|
||||
return errors.Errorf("Invalid input address length: %d", len(in.Address))
|
||||
}
|
||||
if !in.Coins.IsValid() {
|
||||
return errors.Errorf("Invalid input coins %v", in.Coins)
|
||||
}
|
||||
if in.Coins.IsZero() {
|
||||
return errors.New("Input coins cannot be zero")
|
||||
}
|
||||
if in.Sequence <= 0 {
|
||||
return errors.New("Sequence must be greater than 0")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -8,7 +8,6 @@ import (
|
||||
flag "github.com/spf13/pflag"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
"github.com/tendermint/light-client/commands"
|
||||
txcmd "github.com/tendermint/light-client/commands/txs"
|
||||
|
||||
@ -71,7 +70,7 @@ func doSendTx(cmd *cobra.Command, args []string) error {
|
||||
|
||||
func readSendTxFlags(tx *btypes.SendTx) error {
|
||||
// parse to address
|
||||
to, err := hex.DecodeString(StripHex(viper.GetString(ToFlag)))
|
||||
to, err := ParseHexFlag(ToFlag)
|
||||
if err != nil {
|
||||
return errors.Errorf("To address is invalid hex: %v\n", err)
|
||||
}
|
||||
@ -104,76 +103,52 @@ func readSendTxFlags(tx *btypes.SendTx) error {
|
||||
|
||||
/******** AppTx *********/
|
||||
|
||||
type AppFlags struct {
|
||||
Fee string
|
||||
Gas int64
|
||||
Amount string
|
||||
Sequence int
|
||||
func AddAppTxFlags(fs *flag.FlagSet) {
|
||||
fs.String(AmountFlag, "", "Coins to send in the format <amt><coin>,<amt><coin>...")
|
||||
fs.String(FeeFlag, "0mycoin", "Coins for the transaction fee of the format <amt><coin>")
|
||||
fs.Int64(GasFlag, 0, "Amount of gas for this transaction")
|
||||
fs.Int(SequenceFlag, -1, "Sequence number for this transaction")
|
||||
}
|
||||
|
||||
func AppFlagSet() (*flag.FlagSet, AppFlags) {
|
||||
fs := flag.NewFlagSet("", flag.ContinueOnError)
|
||||
|
||||
fs.String("amount", "", "Coins to send in the format <amt><coin>,<amt><coin>...")
|
||||
fs.String("fee", "", "Coins for the transaction fee of the format <amt><coin>")
|
||||
fs.Int64("gas", 0, "Amount of gas for this transaction")
|
||||
fs.Int("sequence", -1, "Sequence number for this transaction")
|
||||
return fs, AppFlags{}
|
||||
}
|
||||
|
||||
// AppTxReader allows us to create AppTx
|
||||
type AppTxReader struct {
|
||||
ChainID string
|
||||
}
|
||||
|
||||
func (t AppTxReader) ReadTxJSON(data []byte, pk crypto.PubKey) (interface{}, error) {
|
||||
return nil, errors.New("Not implemented...")
|
||||
}
|
||||
|
||||
func (t AppTxReader) ReadTxFlags(data *AppFlags, app string, appData []byte, pk crypto.PubKey) (interface{}, error) {
|
||||
// ReadAppTxFlags reads in the standard flags
|
||||
// your command should parse info to set tx.Name and tx.Data
|
||||
func ReadAppTxFlags(tx *btypes.AppTx) error {
|
||||
//parse the fee and amounts into coin types
|
||||
feeCoin, err := btypes.ParseCoin(data.Fee)
|
||||
var err error
|
||||
tx.Fee, err = btypes.ParseCoin(viper.GetString(FeeFlag))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
amountCoins, err := btypes.ParseCoins(data.Amount)
|
||||
amountCoins, err := btypes.ParseCoins(viper.GetString(AmountFlag))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
// get addr if available
|
||||
var addr []byte
|
||||
if !pk.Empty() {
|
||||
addr = pk.Address()
|
||||
}
|
||||
// set the gas
|
||||
tx.Gas = viper.GetInt64(GasFlag)
|
||||
|
||||
// craft the tx
|
||||
input := btypes.TxInput{
|
||||
Address: addr,
|
||||
// craft the inputs and outputs
|
||||
tx.Input = btypes.TxInput{
|
||||
Coins: amountCoins,
|
||||
Sequence: data.Sequence,
|
||||
}
|
||||
if data.Sequence == 1 {
|
||||
input.PubKey = pk
|
||||
}
|
||||
tx := btypes.AppTx{
|
||||
Gas: data.Gas,
|
||||
Fee: feeCoin,
|
||||
Input: input,
|
||||
Name: app,
|
||||
Data: appData,
|
||||
Sequence: viper.GetInt(SequenceFlag),
|
||||
}
|
||||
|
||||
// wrap it in the proper signer thing...
|
||||
send := AppTx{
|
||||
chainID: t.ChainID,
|
||||
Tx: &tx,
|
||||
return nil
|
||||
}
|
||||
|
||||
func WrapAppTx(tx *btypes.AppTx) *AppTx {
|
||||
return &AppTx{
|
||||
chainID: viper.GetString(commands.ChainFlag),
|
||||
Tx: tx,
|
||||
}
|
||||
return &send, nil
|
||||
}
|
||||
|
||||
/** TODO copied from basecoin cli - put in common somewhere? **/
|
||||
|
||||
func ParseHexFlag(flag string) ([]byte, error) {
|
||||
return hex.DecodeString(StripHex(viper.GetString(flag)))
|
||||
}
|
||||
|
||||
// Returns true for non-empty hex-string prefixed with "0x"
|
||||
func isHex(s string) bool {
|
||||
if len(s) > 2 && s[:2] == "0x" {
|
||||
@ -1,72 +1,79 @@
|
||||
package counter
|
||||
|
||||
import (
|
||||
flag "github.com/spf13/pflag"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
wire "github.com/tendermint/go-wire"
|
||||
lightclient "github.com/tendermint/light-client"
|
||||
"github.com/tendermint/light-client/commands"
|
||||
"github.com/tendermint/light-client/commands/txs"
|
||||
txcmd "github.com/tendermint/light-client/commands/txs"
|
||||
|
||||
bcmd "github.com/tendermint/basecoin/cmd/basecli/commands"
|
||||
"github.com/tendermint/basecoin/plugins/counter"
|
||||
btypes "github.com/tendermint/basecoin/types"
|
||||
)
|
||||
|
||||
/**** build out the tx ****/
|
||||
var CounterTxCmd = &cobra.Command{
|
||||
Use: "counter",
|
||||
Short: "add a vote to the counter",
|
||||
Long: `Add a vote to the counter.
|
||||
|
||||
var (
|
||||
_ txs.ReaderMaker = CounterTxMaker{}
|
||||
_ lightclient.TxReader = CounterTxReader{}
|
||||
You must pass --valid for it to count and the countfee will be added to the counter.`,
|
||||
RunE: doCounterTx,
|
||||
}
|
||||
|
||||
const (
|
||||
CountFeeFlag = "countfee"
|
||||
ValidFlag = "valid"
|
||||
)
|
||||
|
||||
type CounterTxMaker struct{}
|
||||
|
||||
func (m CounterTxMaker) MakeReader() (lightclient.TxReader, error) {
|
||||
chainID := viper.GetString(commands.ChainFlag)
|
||||
return CounterTxReader{bcmd.AppTxReader{ChainID: chainID}}, nil
|
||||
func init() {
|
||||
fs := CounterTxCmd.Flags()
|
||||
bcmd.AddAppTxFlags(fs)
|
||||
fs.String(CountFeeFlag, "", "Coins to send in the format <amt><coin>,<amt><coin>...")
|
||||
fs.Bool(ValidFlag, false, "Is count valid?")
|
||||
}
|
||||
|
||||
// define flags
|
||||
func doCounterTx(cmd *cobra.Command, args []string) error {
|
||||
tx := new(btypes.AppTx)
|
||||
// Note: we don't support loading apptx from json currently, so skip that
|
||||
|
||||
type CounterFlags struct {
|
||||
bcmd.AppFlags `mapstructure:",squash"`
|
||||
Valid bool
|
||||
CountFee string
|
||||
}
|
||||
|
||||
func (m CounterTxMaker) Flags() (*flag.FlagSet, interface{}) {
|
||||
fs, app := bcmd.AppFlagSet()
|
||||
fs.String("countfee", "", "Coins to send in the format <amt><coin>,<amt><coin>...")
|
||||
fs.Bool("valid", false, "Is count valid?")
|
||||
return fs, &CounterFlags{AppFlags: app}
|
||||
}
|
||||
|
||||
// parse flags
|
||||
|
||||
type CounterTxReader struct {
|
||||
App bcmd.AppTxReader
|
||||
}
|
||||
|
||||
func (t CounterTxReader) ReadTxJSON(data []byte, pk crypto.PubKey) (interface{}, error) {
|
||||
// TODO: something. maybe?
|
||||
return t.App.ReadTxJSON(data, pk)
|
||||
}
|
||||
|
||||
func (t CounterTxReader) ReadTxFlags(flags interface{}, pk crypto.PubKey) (interface{}, error) {
|
||||
data := flags.(*CounterFlags)
|
||||
countFee, err := btypes.ParseCoins(data.CountFee)
|
||||
// read the standard flags
|
||||
err := bcmd.ReadAppTxFlags(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
// now read the app-specific flags
|
||||
err = readCounterFlags(tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
app := bcmd.WrapAppTx(tx)
|
||||
app.AddSigner(txcmd.GetSigner())
|
||||
|
||||
// Sign if needed and post. This it the work-horse
|
||||
bres, err := txcmd.SignAndPostTx(app)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// output result
|
||||
return txcmd.OutputTx(bres)
|
||||
}
|
||||
|
||||
// readCounterFlags sets the app-specific data in the AppTx
|
||||
func readCounterFlags(tx *btypes.AppTx) error {
|
||||
countFee, err := btypes.ParseCoins(viper.GetString(CountFeeFlag))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx := counter.CounterTx{
|
||||
Valid: viper.GetBool("valid"),
|
||||
Valid: viper.GetBool(ValidFlag),
|
||||
Fee: countFee,
|
||||
}
|
||||
txBytes := wire.BinaryBytes(ctx)
|
||||
|
||||
return t.App.ReadTxFlags(&data.AppFlags, counter.New().Name(), txBytes, pk)
|
||||
tx.Name = counter.New().Name()
|
||||
tx.Data = wire.BinaryBytes(ctx)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@ import (
|
||||
"github.com/tendermint/tmlibs/cli"
|
||||
|
||||
bcmd "github.com/tendermint/basecoin/cmd/basecli/commands"
|
||||
bcount "github.com/tendermint/basecoin/cmd/basecli/counter"
|
||||
)
|
||||
|
||||
// BaseCli represents the base command when called without any subcommands
|
||||
@ -37,13 +38,13 @@ func main() {
|
||||
pr.AddCommand(proofs.TxCmd)
|
||||
pr.AddCommand(proofs.KeyCmd)
|
||||
pr.AddCommand(bcmd.AccountQueryCmd)
|
||||
// pr.AddCommand(bcount.CounterQueryCmd)
|
||||
pr.AddCommand(bcount.CounterQueryCmd)
|
||||
|
||||
// here is how you would add the custom txs... but don't really add demo in your app
|
||||
proofs.TxPresenters.Register("base", bcmd.BaseTxPresenter{})
|
||||
tr := txs.RootCmd
|
||||
tr.AddCommand(bcmd.SendTxCmd)
|
||||
// tr.AddCommand(bcmd.AppTxCmd)
|
||||
tr.AddCommand(bcount.CounterTxCmd)
|
||||
|
||||
// TODO
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user