Separation of Tx from Msg; CodeType
This commit is contained in:
parent
05036e35d2
commit
b95b67d520
@ -227,7 +227,7 @@ func (app *BaseApp) CheckTx(txBytes []byte) (res abci.ResponseCheckTx) {
|
||||
}
|
||||
|
||||
return abci.ResponseCheckTx{
|
||||
Code: result.Code,
|
||||
Code: uint32(result.Code),
|
||||
Data: result.Data,
|
||||
Log: result.Log,
|
||||
GasWanted: result.GasWanted,
|
||||
@ -253,7 +253,7 @@ func (app *BaseApp) DeliverTx(txBytes []byte) (res abci.ResponseDeliverTx) {
|
||||
}
|
||||
|
||||
// After-handler hooks.
|
||||
if result.Code == abci.CodeTypeOK {
|
||||
if result.IsOK() {
|
||||
app.valUpdates = append(app.valUpdates, result.ValidatorUpdates...)
|
||||
} else {
|
||||
// Even though the Code is not OK, there will be some side
|
||||
@ -263,7 +263,7 @@ func (app *BaseApp) DeliverTx(txBytes []byte) (res abci.ResponseDeliverTx) {
|
||||
|
||||
// Tell the blockchain engine (i.e. Tendermint).
|
||||
return abci.ResponseDeliverTx{
|
||||
Code: result.Code,
|
||||
Code: uint32(result.Code),
|
||||
Data: result.Data,
|
||||
Log: result.Log,
|
||||
GasWanted: result.GasWanted,
|
||||
@ -285,8 +285,14 @@ func (app *BaseApp) runTx(isCheckTx bool, txBytes []byte, tx sdk.Tx) (result sdk
|
||||
}
|
||||
}()
|
||||
|
||||
// Validate the Tx.Msg.
|
||||
err := tx.ValidateBasic()
|
||||
// Get the Msg.
|
||||
var msg = tx.GetMsg()
|
||||
if msg == nil {
|
||||
return sdk.ErrInternal("Tx.GetMsg() returned nil").Result()
|
||||
}
|
||||
|
||||
// Validate the Msg.
|
||||
err := msg.ValidateBasic()
|
||||
if err != nil {
|
||||
return err.Result()
|
||||
}
|
||||
@ -297,9 +303,6 @@ func (app *BaseApp) runTx(isCheckTx bool, txBytes []byte, tx sdk.Tx) (result sdk
|
||||
// TODO: override default ante handler w/ custom ante handler.
|
||||
|
||||
// Run the ante handler.
|
||||
if ctx.IsZero() {
|
||||
panic("why? before")
|
||||
}
|
||||
newCtx, result, abort := app.defaultAnteHandler(ctx, tx)
|
||||
if isCheckTx || abort {
|
||||
return result
|
||||
@ -313,9 +316,9 @@ func (app *BaseApp) runTx(isCheckTx bool, txBytes []byte, tx sdk.Tx) (result sdk
|
||||
ctx = ctx.WithMultiStore(msCache)
|
||||
|
||||
// Match and run route.
|
||||
msgType := tx.Type()
|
||||
msgType := msg.Type()
|
||||
handler := app.router.Route(msgType)
|
||||
result = handler(ctx, tx)
|
||||
result = handler(ctx, msg)
|
||||
|
||||
// If result was successful, write to app.msDeliver or app.msCheck.
|
||||
if result.IsOK() {
|
||||
|
||||
@ -22,10 +22,11 @@ type testUpdatePowerTx struct {
|
||||
NewPower int64
|
||||
}
|
||||
|
||||
const txType = "testUpdatePowerTx"
|
||||
const msgType = "testUpdatePowerTx"
|
||||
|
||||
func (tx testUpdatePowerTx) Type() string { return txType }
|
||||
func (tx testUpdatePowerTx) Type() string { return msgType }
|
||||
func (tx testUpdatePowerTx) Get(key interface{}) (value interface{}) { return nil }
|
||||
func (tx testUpdatePowerTx) GetMsg() sdk.Msg { return tx }
|
||||
func (tx testUpdatePowerTx) GetSignBytes() []byte { return nil }
|
||||
func (tx testUpdatePowerTx) ValidateBasic() sdk.Error { return nil }
|
||||
func (tx testUpdatePowerTx) GetSigners() []crypto.Address { return nil }
|
||||
@ -44,7 +45,7 @@ func TestBasic(t *testing.T) {
|
||||
})
|
||||
|
||||
app.SetDefaultAnteHandler(func(ctx sdk.Context, tx sdk.Tx) (newCtx sdk.Context, res sdk.Result, abort bool) { return })
|
||||
app.Router().AddRoute(txType, func(ctx sdk.Context, tx sdk.Tx) sdk.Result {
|
||||
app.Router().AddRoute(msgType, func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
||||
// TODO
|
||||
return sdk.Result{}
|
||||
})
|
||||
|
||||
@ -63,7 +63,7 @@ func (tapp *TestApp) RunCheckTx(tx sdk.Tx) sdk.Result {
|
||||
|
||||
func (tapp *TestApp) RunDeliverTx(tx sdk.Tx) sdk.Result {
|
||||
tapp.ensureBeginBlock()
|
||||
return tapp.BaseApp.runTx(true, nil, tx)
|
||||
return tapp.BaseApp.runTx(false, nil, tx)
|
||||
}
|
||||
|
||||
// NOTE: Skips authentication by wrapping msg in testTx{}.
|
||||
@ -75,7 +75,7 @@ func (tapp *TestApp) RunCheckMsg(msg sdk.Msg) sdk.Result {
|
||||
// NOTE: Skips authentication by wrapping msg in testTx{}.
|
||||
func (tapp *TestApp) RunDeliverMsg(msg sdk.Msg) sdk.Result {
|
||||
var tx = testTx{msg}
|
||||
return tapp.RunCheckTx(tx)
|
||||
return tapp.RunDeliverTx(tx)
|
||||
}
|
||||
|
||||
func (tapp *TestApp) CommitMultiStore() sdk.CommitMultiStore {
|
||||
@ -97,6 +97,7 @@ type testTx struct {
|
||||
sdk.Msg
|
||||
}
|
||||
|
||||
func (tx testTx) GetMsg() sdk.Msg { return tx.Msg }
|
||||
func (tx testTx) GetSigners() []crypto.Address { return nil }
|
||||
func (tx testTx) GetFeePayer() crypto.Address { return nil }
|
||||
func (tx testTx) GetSignatures() []sdk.StdSignature { return nil }
|
||||
|
||||
@ -30,7 +30,11 @@ func TestSendMsg(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
// Run a SendMsg.
|
||||
// Run a Check on SendMsg.
|
||||
res := tba.RunCheckMsg(msg)
|
||||
assert.Equal(t, sdk.CodeOK, res.Code, res.Log)
|
||||
|
||||
// Run a Deliver on SendMsg.
|
||||
res = tba.RunDeliverMsg(msg)
|
||||
assert.Equal(t, sdk.CodeUnrecognizedAddress, res.Code, res.Log)
|
||||
}
|
||||
|
||||
@ -51,10 +51,10 @@ func main() {
|
||||
}
|
||||
|
||||
func DummyHandler(storeKey sdk.StoreKey) sdk.Handler {
|
||||
return func(ctx sdk.Context, tx sdk.Tx) sdk.Result {
|
||||
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
||||
// tx is already unmarshalled
|
||||
key := tx.Get("key").([]byte)
|
||||
value := tx.Get("value").([]byte)
|
||||
key := msg.Get("key").([]byte)
|
||||
value := msg.Get("value").([]byte)
|
||||
|
||||
store := ctx.KVStore(storeKey)
|
||||
store.Set(key, value)
|
||||
|
||||
@ -7,6 +7,7 @@ import (
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
)
|
||||
|
||||
// An sdk.Tx which is its own sdk.Msg.
|
||||
type dummyTx struct {
|
||||
key []byte
|
||||
value []byte
|
||||
@ -30,6 +31,10 @@ func (tx dummyTx) Type() string {
|
||||
return "dummy"
|
||||
}
|
||||
|
||||
func (tx dummyTx) GetMsg() sdk.Msg {
|
||||
return tx
|
||||
}
|
||||
|
||||
func (tx dummyTx) GetSignBytes() []byte {
|
||||
return tx.bytes
|
||||
}
|
||||
|
||||
@ -2,25 +2,36 @@ package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/tendermint/go-crypto"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
type CodeType uint32
|
||||
|
||||
func (code CodeType) IsOK() bool {
|
||||
if code == CodeOK {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
// ABCI Response Codes
|
||||
// Base SDK reserves 0 ~ 99.
|
||||
CodeOK uint32 = 0
|
||||
CodeInternal = 1
|
||||
CodeTxParse = 2
|
||||
CodeBadNonce = 3
|
||||
CodeUnauthorized = 4
|
||||
CodeInsufficientFunds = 5
|
||||
CodeUnknownRequest = 6
|
||||
CodeUnrecognizedAddress = 7
|
||||
CodeInvalidSequence = 8
|
||||
CodeOK CodeType = 0
|
||||
CodeInternal CodeType = 1
|
||||
CodeTxParse CodeType = 2
|
||||
CodeBadNonce CodeType = 3
|
||||
CodeUnauthorized CodeType = 4
|
||||
CodeInsufficientFunds CodeType = 5
|
||||
CodeUnknownRequest CodeType = 6
|
||||
CodeUnrecognizedAddress CodeType = 7
|
||||
CodeInvalidSequence CodeType = 8
|
||||
)
|
||||
|
||||
// NOTE: Don't stringer this, we'll put better messages in later.
|
||||
func CodeToDefaultMsg(code uint32) string {
|
||||
func CodeToDefaultMsg(code CodeType) string {
|
||||
switch code {
|
||||
case CodeInternal:
|
||||
return "Internal error"
|
||||
@ -71,8 +82,8 @@ func ErrUnknownRequest(msg string) Error {
|
||||
return newError(CodeUnknownRequest, msg)
|
||||
}
|
||||
|
||||
func ErrUnrecognizedAddress(msg string) Error {
|
||||
return newError(CodeUnrecognizedAddress, msg)
|
||||
func ErrUnrecognizedAddress(addr crypto.Address) Error {
|
||||
return newError(CodeUnrecognizedAddress, addr.String())
|
||||
}
|
||||
|
||||
func ErrInvalidSequence(msg string) Error {
|
||||
@ -84,7 +95,7 @@ func ErrInvalidSequence(msg string) Error {
|
||||
|
||||
type Error interface {
|
||||
Error() string
|
||||
ABCICode() uint32
|
||||
ABCICode() CodeType
|
||||
ABCILog() string
|
||||
Trace(msg string) Error
|
||||
TraceCause(cause error, msg string) Error
|
||||
@ -92,7 +103,7 @@ type Error interface {
|
||||
Result() Result
|
||||
}
|
||||
|
||||
func NewError(code uint32, msg string) Error {
|
||||
func NewError(code CodeType, msg string) Error {
|
||||
return newError(code, msg)
|
||||
}
|
||||
|
||||
@ -107,39 +118,39 @@ func (ti traceItem) String() string {
|
||||
}
|
||||
|
||||
type sdkError struct {
|
||||
code uint32
|
||||
msg string
|
||||
cause error
|
||||
trace []traceItem
|
||||
code CodeType
|
||||
msg string
|
||||
cause error
|
||||
traces []traceItem
|
||||
}
|
||||
|
||||
func newError(code uint32, msg string) *sdkError {
|
||||
func newError(code CodeType, msg string) *sdkError {
|
||||
// TODO capture stacktrace if ENV is set.
|
||||
if msg == "" {
|
||||
msg = CodeToDefaultMsg(code)
|
||||
}
|
||||
return &sdkError{
|
||||
code: code,
|
||||
msg: msg,
|
||||
cause: nil,
|
||||
trace: nil,
|
||||
code: code,
|
||||
msg: msg,
|
||||
cause: nil,
|
||||
traces: nil,
|
||||
}
|
||||
}
|
||||
|
||||
// Implements ABCIError.
|
||||
func (err *sdkError) Error() string {
|
||||
return fmt.Sprintf("Error{%d:%s,%v,%v}", err.code, err.msg, err.cause, len(err.trace))
|
||||
return fmt.Sprintf("Error{%d:%s,%v,%v}", err.code, err.msg, err.cause, len(err.traces))
|
||||
}
|
||||
|
||||
// Implements ABCIError.
|
||||
func (err *sdkError) ABCICode() uint32 {
|
||||
func (err *sdkError) ABCICode() CodeType {
|
||||
return err.code
|
||||
}
|
||||
|
||||
// Implements ABCIError.
|
||||
func (err *sdkError) ABCILog() string {
|
||||
traceLog := ""
|
||||
for _, ti := range err.trace {
|
||||
for _, ti := range err.traces {
|
||||
traceLog += ti.String() + "\n"
|
||||
}
|
||||
return fmt.Sprintf("msg: %v\ntrace:\n%v",
|
||||
@ -150,7 +161,17 @@ func (err *sdkError) ABCILog() string {
|
||||
|
||||
// Add tracing information with msg.
|
||||
func (err *sdkError) Trace(msg string) Error {
|
||||
_, fn, line, ok := runtime.Caller(1)
|
||||
return err.doTrace(msg, 2)
|
||||
}
|
||||
|
||||
// Add tracing information with cause and msg.
|
||||
func (err *sdkError) TraceCause(cause error, msg string) Error {
|
||||
err.cause = cause
|
||||
return err.doTrace(msg, 2)
|
||||
}
|
||||
|
||||
func (err *sdkError) doTrace(msg string, n int) Error {
|
||||
_, fn, line, ok := runtime.Caller(n)
|
||||
if !ok {
|
||||
if fn == "" {
|
||||
fn = "<unknown>"
|
||||
@ -161,7 +182,7 @@ func (err *sdkError) Trace(msg string) Error {
|
||||
}
|
||||
// Include file & line number & msg.
|
||||
// Do not include the whole stack trace.
|
||||
err.trace = append(err.trace, traceItem{
|
||||
err.traces = append(err.traces, traceItem{
|
||||
filename: fn,
|
||||
lineno: line,
|
||||
msg: msg,
|
||||
@ -169,12 +190,6 @@ func (err *sdkError) Trace(msg string) Error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Add tracing information with cause and msg.
|
||||
func (err *sdkError) TraceCause(cause error, msg string) Error {
|
||||
err.cause = cause
|
||||
return err.Trace(msg)
|
||||
}
|
||||
|
||||
func (err *sdkError) Cause() error {
|
||||
return err.cause
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
package types
|
||||
|
||||
type Handler func(ctx Context, tx Tx) Result
|
||||
type Handler func(ctx Context, msg Msg) Result
|
||||
|
||||
// If newCtx.IsZero(), ctx is used instead.
|
||||
type AnteHandler func(ctx Context, tx Tx) (newCtx Context, result Result, abort bool)
|
||||
|
||||
@ -9,7 +9,7 @@ import (
|
||||
type Result struct {
|
||||
|
||||
// Code is the response code, is stored back on the chain.
|
||||
Code uint32
|
||||
Code CodeType
|
||||
|
||||
// Data is any data returned from the app.
|
||||
Data []byte
|
||||
@ -36,5 +36,5 @@ type Result struct {
|
||||
|
||||
// TODO: In the future, more codes may be OK.
|
||||
func (res Result) IsOK() bool {
|
||||
return res.Code == CodeOK
|
||||
return res.Code.IsOK()
|
||||
}
|
||||
|
||||
@ -27,7 +27,9 @@ type Msg interface {
|
||||
}
|
||||
|
||||
type Tx interface {
|
||||
Msg
|
||||
|
||||
// Gets the Msg.
|
||||
GetMsg() Msg
|
||||
|
||||
// The address that pays the base fee for this message. The fee is
|
||||
// deducted before the Msg is processed.
|
||||
@ -50,6 +52,7 @@ type StdTx struct {
|
||||
Signatures []StdSignature
|
||||
}
|
||||
|
||||
func (tx StdTx) GetMsg() Msg { return tx.Msg }
|
||||
func (tx StdTx) GetFeePayer() crypto.Address { return tx.Signatures[0].PubKey.Address() }
|
||||
func (tx StdTx) GetSignatures() []StdSignature { return tx.Signatures }
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ func NewAnteHandler(accountMapper sdk.AccountMapper) sdk.AnteHandler {
|
||||
payerAcc := accountMapper.GetAccount(ctx, payerAddr)
|
||||
if payerAcc == nil {
|
||||
return ctx,
|
||||
sdk.ErrUnrecognizedAddress("").Result(),
|
||||
sdk.ErrUnrecognizedAddress(payerAddr).Result(),
|
||||
true
|
||||
}
|
||||
// TODO: Charge fee from payerAcc.
|
||||
@ -29,61 +29,66 @@ func NewAnteHandler(accountMapper sdk.AccountMapper) sdk.AnteHandler {
|
||||
// create a Tx with no payer.
|
||||
}
|
||||
|
||||
// Ensure that signatures are correct.
|
||||
var signerAddrs = tx.GetSigners()
|
||||
var signerAccs = make([]sdk.Account, len(signerAddrs))
|
||||
var signatures = tx.GetSignatures()
|
||||
var sigs = tx.GetSignatures()
|
||||
|
||||
// Assert that there are signers.
|
||||
if len(signerAddrs) == 0 {
|
||||
if !bam.IsTestAppTx(tx) {
|
||||
// Assert that there are signatures.
|
||||
if !bam.IsTestAppTx(tx) {
|
||||
if len(sigs) == 0 {
|
||||
return ctx,
|
||||
sdk.ErrUnauthorized("no signers").Result(),
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that sigs are correct.
|
||||
var msg = tx.GetMsg()
|
||||
var signerAddrs = msg.GetSigners()
|
||||
var signerAccs = make([]sdk.Account, len(signerAddrs))
|
||||
|
||||
// Assert that number of signatures is correct.
|
||||
if len(signatures) != len(signerAddrs) {
|
||||
return ctx,
|
||||
sdk.ErrUnauthorized("wrong number of signers").Result(),
|
||||
true
|
||||
}
|
||||
if !bam.IsTestAppTx(tx) {
|
||||
if len(sigs) != len(signerAddrs) {
|
||||
return ctx,
|
||||
sdk.ErrUnauthorized("wrong number of signers").Result(),
|
||||
true
|
||||
}
|
||||
|
||||
// Check each nonce and sig.
|
||||
for i, sig := range signatures {
|
||||
// Check each nonce and sig.
|
||||
// TODO Refactor out.
|
||||
for i, sig := range sigs {
|
||||
|
||||
var signerAcc = accountMapper.GetAccount(ctx, signerAddrs[i])
|
||||
signerAccs[i] = signerAcc
|
||||
var signerAcc = accountMapper.GetAccount(ctx, signerAddrs[i])
|
||||
signerAccs[i] = signerAcc
|
||||
|
||||
// If no pubkey, set pubkey.
|
||||
if signerAcc.GetPubKey() == nil {
|
||||
err := signerAcc.SetPubKey(sig.PubKey)
|
||||
if err != nil {
|
||||
// If no pubkey, set pubkey.
|
||||
if signerAcc.GetPubKey() == nil {
|
||||
err := signerAcc.SetPubKey(sig.PubKey)
|
||||
if err != nil {
|
||||
return ctx,
|
||||
sdk.ErrInternal("setting PubKey on signer").Result(),
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
// Check and increment sequence number.
|
||||
seq := signerAcc.GetSequence()
|
||||
if seq != sig.Sequence {
|
||||
return ctx,
|
||||
sdk.ErrInternal("setting PubKey on signer").Result(),
|
||||
sdk.ErrInvalidSequence("").Result(),
|
||||
true
|
||||
}
|
||||
}
|
||||
signerAcc.SetSequence(seq + 1)
|
||||
|
||||
// Check and increment sequence number.
|
||||
seq := signerAcc.GetSequence()
|
||||
if seq != sig.Sequence {
|
||||
return ctx,
|
||||
sdk.ErrInvalidSequence("").Result(),
|
||||
true
|
||||
}
|
||||
signerAcc.SetSequence(seq + 1)
|
||||
// Check sig.
|
||||
if !sig.PubKey.VerifyBytes(msg.GetSignBytes(), sig.Signature) {
|
||||
return ctx,
|
||||
sdk.ErrUnauthorized("").Result(),
|
||||
true
|
||||
}
|
||||
|
||||
// Check sig.
|
||||
if !sig.PubKey.VerifyBytes(tx.GetSignBytes(), sig.Signature) {
|
||||
return ctx,
|
||||
sdk.ErrUnauthorized("").Result(),
|
||||
true
|
||||
// Save the account.
|
||||
accountMapper.SetAccount(ctx, signerAcc)
|
||||
}
|
||||
|
||||
// Save the account.
|
||||
accountMapper.SetAccount(ctx, signerAcc)
|
||||
}
|
||||
|
||||
ctx = WithSigners(ctx, signerAccs)
|
||||
|
||||
@ -5,19 +5,21 @@ import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
type CodeType = sdk.CodeType
|
||||
|
||||
const (
|
||||
// Coin errors reserve 100 ~ 199.
|
||||
CodeInvalidInput uint32 = 101
|
||||
CodeInvalidOutput uint32 = 102
|
||||
CodeInvalidAddress uint32 = 103
|
||||
CodeUnknownAddress uint32 = 104
|
||||
CodeInsufficientCoins uint32 = 105
|
||||
CodeInvalidCoins uint32 = 106
|
||||
CodeUnknownRequest uint32 = sdk.CodeUnknownRequest
|
||||
CodeInvalidInput CodeType = 101
|
||||
CodeInvalidOutput CodeType = 102
|
||||
CodeInvalidAddress CodeType = 103
|
||||
CodeUnknownAddress CodeType = 104
|
||||
CodeInsufficientCoins CodeType = 105
|
||||
CodeInvalidCoins CodeType = 106
|
||||
CodeUnknownRequest CodeType = sdk.CodeUnknownRequest
|
||||
)
|
||||
|
||||
// NOTE: Don't stringer this, we'll put better messages in later.
|
||||
func codeToDefaultMsg(code uint32) string {
|
||||
func codeToDefaultMsg(code CodeType) string {
|
||||
switch code {
|
||||
case CodeInvalidInput:
|
||||
return "Invalid input coins"
|
||||
@ -83,7 +85,7 @@ func ErrUnknownRequest(msg string) sdk.Error {
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
func msgOrDefaultMsg(msg string, code uint32) string {
|
||||
func msgOrDefaultMsg(msg string, code CodeType) string {
|
||||
if msg != "" {
|
||||
return msg
|
||||
} else {
|
||||
@ -91,7 +93,7 @@ func msgOrDefaultMsg(msg string, code uint32) string {
|
||||
}
|
||||
}
|
||||
|
||||
func newError(code uint32, msg string) sdk.Error {
|
||||
func newError(code CodeType, msg string) sdk.Error {
|
||||
msg = msgOrDefaultMsg(msg, code)
|
||||
return sdk.NewError(code, msg)
|
||||
}
|
||||
|
||||
@ -1,23 +1,23 @@
|
||||
package bank
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"reflect"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// Handle all "bank" type messages.
|
||||
func NewHandler(am sdk.AccountMapper) sdk.Handler {
|
||||
|
||||
return func(ctx sdk.Context, tx sdk.Tx) sdk.Result {
|
||||
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
||||
cm := CoinMapper{am}
|
||||
msg := tx.(sdk.Msg)
|
||||
switch msg := msg.(type) {
|
||||
case SendMsg:
|
||||
return handleSendMsg(ctx, cm, msg)
|
||||
case IssueMsg:
|
||||
return handleIssueMsg(ctx, cm, msg)
|
||||
default:
|
||||
errMsg := "Unrecognized bank Tx type: " + reflect.TypeOf(tx).Name()
|
||||
errMsg := "Unrecognized bank Msg type: " + reflect.TypeOf(msg).Name()
|
||||
return sdk.ErrUnknownRequest(errMsg).Result()
|
||||
}
|
||||
}
|
||||
@ -31,14 +31,14 @@ func handleSendMsg(ctx sdk.Context, cm CoinMapper, msg SendMsg) sdk.Result {
|
||||
for _, in := range msg.Inputs {
|
||||
_, err := cm.SubtractCoins(ctx, in.Address, in.Coins)
|
||||
if err != nil {
|
||||
return ErrInvalidInput("").TraceCause(err, "").Result()
|
||||
return err.Result()
|
||||
}
|
||||
}
|
||||
|
||||
for _, out := range msg.Outputs {
|
||||
_, err := cm.AddCoins(ctx, out.Address, out.Coins)
|
||||
if err != nil {
|
||||
return ErrInvalidOutput("").TraceCause(err, "").Result()
|
||||
return err.Result()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -13,10 +13,10 @@ type CoinMapper struct {
|
||||
}
|
||||
|
||||
// SubtractCoins subtracts amt from the coins at the addr.
|
||||
func (cm CoinMapper) SubtractCoins(ctx sdk.Context, addr crypto.Address, amt sdk.Coins) (sdk.Coins, error) {
|
||||
func (cm CoinMapper) SubtractCoins(ctx sdk.Context, addr crypto.Address, amt sdk.Coins) (sdk.Coins, sdk.Error) {
|
||||
acc := cm.am.GetAccount(ctx, addr)
|
||||
if acc == nil {
|
||||
return amt, fmt.Errorf("Sending account (%s) does not exist", addr)
|
||||
return amt, sdk.ErrUnrecognizedAddress(addr)
|
||||
}
|
||||
|
||||
coins := acc.GetCoins()
|
||||
@ -31,7 +31,7 @@ func (cm CoinMapper) SubtractCoins(ctx sdk.Context, addr crypto.Address, amt sdk
|
||||
}
|
||||
|
||||
// AddCoins adds amt to the coins at the addr.
|
||||
func (cm CoinMapper) AddCoins(ctx sdk.Context, addr crypto.Address, amt sdk.Coins) (sdk.Coins, error) {
|
||||
func (cm CoinMapper) AddCoins(ctx sdk.Context, addr crypto.Address, amt sdk.Coins) (sdk.Coins, sdk.Error) {
|
||||
acc := cm.am.GetAccount(ctx, addr)
|
||||
if acc == nil {
|
||||
acc = cm.am.NewAccountWithAddress(ctx, addr)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user