Basecoin TMSP test; Result logs
This commit is contained in:
parent
ed9dd875a7
commit
83e7c9dab1
|
@ -47,9 +47,9 @@ func (app *Basecoin) SetOption(key string, value string) (log string) {
|
||||||
return "Error decoding setAccount message: " + err.Error()
|
return "Error decoding setAccount message: " + err.Error()
|
||||||
}
|
}
|
||||||
accBytes := wire.BinaryBytes(setAccount)
|
accBytes := wire.BinaryBytes(setAccount)
|
||||||
err = app.eyesCli.SetSync(setAccount.PubKey.Address(), accBytes)
|
res := app.eyesCli.SetSync(setAccount.PubKey.Address(), accBytes)
|
||||||
if err != nil {
|
if res.IsErr() {
|
||||||
return "Error saving account: " + err.Error()
|
return "Error saving account: " + res.Error()
|
||||||
}
|
}
|
||||||
return "Success"
|
return "Success"
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,6 @@ func (app *Basecoin) CheckTx(txBytes []byte) (res tmsp.Result) {
|
||||||
|
|
||||||
// TMSP::Query
|
// TMSP::Query
|
||||||
func (app *Basecoin) Query(query []byte) (res tmsp.Result) {
|
func (app *Basecoin) Query(query []byte) (res tmsp.Result) {
|
||||||
return tmsp.OK
|
|
||||||
res = app.eyesCli.GetSync(query)
|
res = app.eyesCli.GetSync(query)
|
||||||
if res.IsErr() {
|
if res.IsErr() {
|
||||||
return res.PrependLog("Error querying eyesCli")
|
return res.PrependLog("Error querying eyesCli")
|
||||||
|
|
|
@ -22,24 +22,24 @@ func ExecTx(state *State, tx types.Tx, isCheckTx bool, evc events.Fireable) tmsp
|
||||||
// First, get inputs
|
// First, get inputs
|
||||||
accounts, res := getInputs(state, tx.Inputs)
|
accounts, res := getInputs(state, tx.Inputs)
|
||||||
if res.IsErr() {
|
if res.IsErr() {
|
||||||
return res
|
return res.PrependLog("in getInputs()")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then, get or make outputs.
|
// Then, get or make outputs.
|
||||||
accounts, res = getOrMakeOutputs(state, accounts, tx.Outputs)
|
accounts, res = getOrMakeOutputs(state, accounts, tx.Outputs)
|
||||||
if res.IsErr() {
|
if res.IsErr() {
|
||||||
return res
|
return res.PrependLog("in getOrMakeOutputs()")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate inputs and outputs
|
// Validate inputs and outputs
|
||||||
signBytes := tx.SignBytes(state.GetChainID())
|
signBytes := tx.SignBytes(state.GetChainID())
|
||||||
inTotal, res := validateInputs(state, accounts, signBytes, tx.Inputs)
|
inTotal, res := validateInputs(state, accounts, signBytes, tx.Inputs)
|
||||||
if res.IsErr() {
|
if res.IsErr() {
|
||||||
return res
|
return res.PrependLog("in validateInputs()")
|
||||||
}
|
}
|
||||||
outTotal, res := validateOutputs(tx.Outputs)
|
outTotal, res := validateOutputs(tx.Outputs)
|
||||||
if res.IsErr() {
|
if res.IsErr() {
|
||||||
return res
|
return res.PrependLog("in validateOutputs()")
|
||||||
}
|
}
|
||||||
if outTotal > inTotal {
|
if outTotal > inTotal {
|
||||||
return tmsp.ErrBaseInsufficientFunds
|
return tmsp.ErrBaseInsufficientFunds
|
||||||
|
@ -73,8 +73,7 @@ func ExecTx(state *State, tx types.Tx, isCheckTx bool, evc events.Fireable) tmsp
|
||||||
// First, get input account
|
// First, get input account
|
||||||
inAcc := state.GetAccount(tx.Input.Address)
|
inAcc := state.GetAccount(tx.Input.Address)
|
||||||
if inAcc == nil {
|
if inAcc == nil {
|
||||||
log.Info(Fmt("Can't find in account %X", tx.Input.Address))
|
return tmsp.ErrBaseUnknownAddress
|
||||||
return tmsp.ErrBaseInvalidAddress
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate input
|
// Validate input
|
||||||
|
@ -87,7 +86,7 @@ func ExecTx(state *State, tx types.Tx, isCheckTx bool, evc events.Fireable) tmsp
|
||||||
res := validateInput(state, inAcc, signBytes, tx.Input)
|
res := validateInput(state, inAcc, signBytes, tx.Input)
|
||||||
if res.IsErr() {
|
if res.IsErr() {
|
||||||
log.Info(Fmt("validateInput failed on %X: %v", tx.Input.Address, res))
|
log.Info(Fmt("validateInput failed on %X: %v", tx.Input.Address, res))
|
||||||
return res
|
return res.PrependLog("in validateInput()")
|
||||||
}
|
}
|
||||||
if tx.Input.Amount < tx.Fee {
|
if tx.Input.Amount < tx.Fee {
|
||||||
log.Info(Fmt("Sender did not send enough to cover the fee %X", tx.Input.Address))
|
log.Info(Fmt("Sender did not send enough to cover the fee %X", tx.Input.Address))
|
||||||
|
@ -98,7 +97,7 @@ func ExecTx(state *State, tx types.Tx, isCheckTx bool, evc events.Fireable) tmsp
|
||||||
if strings.HasPrefix(string(tx.Address), "gov/") {
|
if strings.HasPrefix(string(tx.Address), "gov/") {
|
||||||
// This is a gov call.
|
// This is a gov call.
|
||||||
} else {
|
} else {
|
||||||
return tmsp.ErrBaseInvalidAddress.AppendLog(Fmt("Unrecognized address %X", tx.Address))
|
return tmsp.ErrBaseUnknownAddress.AppendLog(Fmt("Unrecognized address %X", tx.Address))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Good!
|
// Good!
|
||||||
|
@ -109,13 +108,13 @@ func ExecTx(state *State, tx types.Tx, isCheckTx bool, evc events.Fireable) tmsp
|
||||||
|
|
||||||
// If this is AppendTx, actually save accounts
|
// If this is AppendTx, actually save accounts
|
||||||
if !isCheckTx {
|
if !isCheckTx {
|
||||||
state.SetAccount(inAcc)
|
state.SetAccount(tx.Input.Address, inAcc)
|
||||||
// NOTE: value is dangling.
|
// NOTE: value is dangling.
|
||||||
// XXX: don't just give it back
|
// XXX: don't just give it back
|
||||||
inAcc.Balance += value
|
inAcc.Balance += value
|
||||||
// TODO: logic.
|
// TODO: logic.
|
||||||
// TODO: persist
|
// TODO: persist
|
||||||
// state.SetAccount(inAcc)
|
// state.SetAccount(tx.Input.Address, inAcc)
|
||||||
log.Info("Successful execution")
|
log.Info("Successful execution")
|
||||||
// Fire events
|
// Fire events
|
||||||
/*
|
/*
|
||||||
|
@ -152,7 +151,7 @@ func getInputs(state types.AccountGetter, ins []types.TxInput) (map[string]*type
|
||||||
}
|
}
|
||||||
acc := state.GetAccount(in.Address)
|
acc := state.GetAccount(in.Address)
|
||||||
if acc == nil {
|
if acc == nil {
|
||||||
return nil, tmsp.ErrBaseInvalidAddress
|
return nil, tmsp.ErrBaseUnknownAddress
|
||||||
}
|
}
|
||||||
// PubKey should be present in either "account" or "in"
|
// PubKey should be present in either "account" or "in"
|
||||||
if res := checkInputPubKey(in.Address, acc, in); res.IsErr() {
|
if res := checkInputPubKey(in.Address, acc, in); res.IsErr() {
|
||||||
|
@ -192,15 +191,18 @@ func getOrMakeOutputs(state types.AccountGetter, accounts map[string]*types.Acco
|
||||||
func checkInputPubKey(address []byte, acc *types.Account, in types.TxInput) tmsp.Result {
|
func checkInputPubKey(address []byte, acc *types.Account, in types.TxInput) tmsp.Result {
|
||||||
if acc.PubKey == nil {
|
if acc.PubKey == nil {
|
||||||
if in.PubKey == nil {
|
if in.PubKey == nil {
|
||||||
return tmsp.ErrBaseUnknownPubKey
|
return tmsp.ErrBaseUnknownPubKey.AppendLog("PubKey not present in either acc or input")
|
||||||
}
|
}
|
||||||
if !bytes.Equal(in.PubKey.Address(), address) {
|
if !bytes.Equal(in.PubKey.Address(), address) {
|
||||||
return tmsp.ErrBaseInvalidPubKey
|
return tmsp.ErrBaseInvalidPubKey.AppendLog("Input PubKey address does not match address")
|
||||||
}
|
}
|
||||||
acc.PubKey = in.PubKey
|
acc.PubKey = in.PubKey
|
||||||
} else {
|
} else {
|
||||||
if in.PubKey != nil {
|
if in.PubKey != nil {
|
||||||
return tmsp.ErrBaseInvalidPubKey
|
// NOTE: allow redundant pubkey.
|
||||||
|
if !bytes.Equal(in.PubKey.Address(), address) {
|
||||||
|
return tmsp.ErrBaseInvalidPubKey.AppendLog("Input PubKey address does not match address")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tmsp.OK
|
return tmsp.OK
|
||||||
|
@ -240,7 +242,7 @@ func validateInput(state *State, acc *types.Account, signBytes []byte, in types.
|
||||||
}
|
}
|
||||||
// Check signatures
|
// Check signatures
|
||||||
if !acc.PubKey.VerifyBytes(signBytes, in.Signature) {
|
if !acc.PubKey.VerifyBytes(signBytes, in.Signature) {
|
||||||
return tmsp.ErrBaseInvalidSignature
|
return tmsp.ErrBaseInvalidSignature.AppendLog(Fmt("SignBytes: %X", signBytes))
|
||||||
}
|
}
|
||||||
return tmsp.OK
|
return tmsp.OK
|
||||||
}
|
}
|
||||||
|
@ -271,7 +273,7 @@ func adjustByInputs(state *State, accounts map[string]*types.Account, ins []type
|
||||||
state.SetCheckAccount(in.Address, acc.Sequence, acc.Balance)
|
state.SetCheckAccount(in.Address, acc.Sequence, acc.Balance)
|
||||||
if !isCheckTx {
|
if !isCheckTx {
|
||||||
// NOTE: Must be set in deterministic order
|
// NOTE: Must be set in deterministic order
|
||||||
state.SetAccount(acc)
|
state.SetAccount(in.Address, acc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -286,7 +288,7 @@ func adjustByOutputs(state *State, accounts map[string]*types.Account, outs []ty
|
||||||
if !isCheckTx {
|
if !isCheckTx {
|
||||||
state.SetCheckAccount(out.Address, acc.Sequence, acc.Balance)
|
state.SetCheckAccount(out.Address, acc.Sequence, acc.Balance)
|
||||||
// NOTE: Must be set in deterministic order
|
// NOTE: Must be set in deterministic order
|
||||||
state.SetAccount(acc)
|
state.SetAccount(out.Address, acc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,9 +79,9 @@ func (s *State) GetAccount(addr []byte) *types.Account {
|
||||||
return &acc
|
return &acc
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *State) SetAccount(acc *types.Account) {
|
func (s *State) SetAccount(address []byte, acc *types.Account) {
|
||||||
accBytes := wire.BinaryBytes(acc)
|
accBytes := wire.BinaryBytes(acc)
|
||||||
res := s.eyesCli.SetSync(acc.PubKey.Address(), accBytes)
|
res := s.eyesCli.SetSync(address, accBytes)
|
||||||
if res.IsErr() {
|
if res.IsErr() {
|
||||||
panic("Error storing account: " + res.Error())
|
panic("Error storing account: " + res.Error())
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/tendermint/basecoin/app"
|
||||||
|
"github.com/tendermint/basecoin/tests"
|
||||||
|
"github.com/tendermint/basecoin/types"
|
||||||
|
. "github.com/tendermint/go-common"
|
||||||
|
"github.com/tendermint/go-wire"
|
||||||
|
eyescli "github.com/tendermint/merkleeyes/client"
|
||||||
|
_ "github.com/tendermint/tendermint/rpc/core/types" // Register RPCResponse > Result types
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get the "test" account.
|
||||||
|
PrivKey: 019F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A0867D3B5EAF0C0BF6B5A602D359DAECC86A7A74053490EC37AE08E71360587C870
|
||||||
|
PubKey: 0167D3B5EAF0C0BF6B5A602D359DAECC86A7A74053490EC37AE08E71360587C870
|
||||||
|
Address: D9B727742AA29FA638DC63D70813C976014C4CE0
|
||||||
|
*/
|
||||||
|
func main() {
|
||||||
|
eyesCli := eyescli.NewLocalClient()
|
||||||
|
bcApp := app.NewBasecoin(eyesCli)
|
||||||
|
fmt.Println(bcApp.Info())
|
||||||
|
|
||||||
|
tPriv := tests.PrivAccountFromSecret("test")
|
||||||
|
tPriv2 := tests.PrivAccountFromSecret("test2")
|
||||||
|
|
||||||
|
// Seed Basecoin with account
|
||||||
|
tAcc := tPriv.Account
|
||||||
|
tAcc.Balance = 1000
|
||||||
|
bcApp.SetOption("chainID", "test_chain_id")
|
||||||
|
bcApp.SetOption("account", string(wire.JSONBytes(tAcc)))
|
||||||
|
|
||||||
|
// Construct a SendTx signature
|
||||||
|
tx := &types.SendTx{
|
||||||
|
Inputs: []types.TxInput{
|
||||||
|
types.TxInput{
|
||||||
|
Address: tPriv.Account.PubKey.Address(),
|
||||||
|
PubKey: tPriv.Account.PubKey, // TODO is this needed?
|
||||||
|
Amount: 1,
|
||||||
|
Sequence: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Outputs: []types.TxOutput{
|
||||||
|
types.TxOutput{
|
||||||
|
Address: tPriv2.Account.PubKey.Address(),
|
||||||
|
Amount: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sign request
|
||||||
|
signBytes := tx.SignBytes("test_chain_id")
|
||||||
|
fmt.Printf("SIGNBYTES %X", signBytes)
|
||||||
|
sig := tPriv.PrivKey.Sign(signBytes)
|
||||||
|
tx.Inputs[0].Signature = sig
|
||||||
|
//fmt.Println("tx:", tx)
|
||||||
|
|
||||||
|
// Write request
|
||||||
|
txBytes := wire.BinaryBytes(tx)
|
||||||
|
res := bcApp.AppendTx(txBytes)
|
||||||
|
fmt.Println(res)
|
||||||
|
}
|
|
@ -48,10 +48,10 @@ type TxInput struct {
|
||||||
|
|
||||||
func (txIn TxInput) ValidateBasic() tmsp.Result {
|
func (txIn TxInput) ValidateBasic() tmsp.Result {
|
||||||
if len(txIn.Address) != 20 {
|
if len(txIn.Address) != 20 {
|
||||||
return tmsp.ErrBaseInvalidAddress
|
return tmsp.ErrBaseInvalidAddress.AppendLog("(in TxInput)")
|
||||||
}
|
}
|
||||||
if txIn.Amount == 0 {
|
if txIn.Amount == 0 {
|
||||||
return tmsp.ErrBaseInvalidAmount
|
return tmsp.ErrBaseInvalidAmount.AppendLog("(in TxInput)")
|
||||||
}
|
}
|
||||||
return tmsp.OK
|
return tmsp.OK
|
||||||
}
|
}
|
||||||
|
@ -74,10 +74,10 @@ type TxOutput struct {
|
||||||
|
|
||||||
func (txOut TxOutput) ValidateBasic() tmsp.Result {
|
func (txOut TxOutput) ValidateBasic() tmsp.Result {
|
||||||
if len(txOut.Address) != 20 {
|
if len(txOut.Address) != 20 {
|
||||||
return tmsp.ErrBaseInvalidAddress
|
return tmsp.ErrBaseInvalidAddress.AppendLog("(in TxOutput)")
|
||||||
}
|
}
|
||||||
if txOut.Amount == 0 {
|
if txOut.Amount == 0 {
|
||||||
return tmsp.ErrBaseInvalidAmount
|
return tmsp.ErrBaseInvalidAmount.AppendLog("(in TxOutput)")
|
||||||
}
|
}
|
||||||
return tmsp.OK
|
return tmsp.OK
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue