2017-10-23 12:16:10 -07:00
|
|
|
package bonus
|
2017-06-29 12:21:57 -07:00
|
|
|
|
2017-07-30 14:51:57 -07:00
|
|
|
import (
|
|
|
|
"strings"
|
2017-06-30 04:55:25 -07:00
|
|
|
|
2017-07-30 14:51:57 -07:00
|
|
|
abci "github.com/tendermint/abci/types"
|
|
|
|
wire "github.com/tendermint/go-wire"
|
|
|
|
"github.com/tendermint/go-wire/data"
|
2017-07-06 05:23:38 -07:00
|
|
|
|
2017-08-21 14:13:58 -07:00
|
|
|
sdk "github.com/cosmos/cosmos-sdk"
|
|
|
|
"github.com/cosmos/cosmos-sdk/stack"
|
|
|
|
"github.com/cosmos/cosmos-sdk/state"
|
2017-07-30 14:51:57 -07:00
|
|
|
)
|
2017-06-29 12:21:57 -07:00
|
|
|
|
2017-07-30 14:51:57 -07:00
|
|
|
//nolint
|
|
|
|
const (
|
|
|
|
NameMultiplexer = "mplx"
|
|
|
|
)
|
2017-06-29 12:21:57 -07:00
|
|
|
|
2017-07-30 14:51:57 -07:00
|
|
|
// Multiplexer grabs a MultiTx and sends them sequentially down the line
|
|
|
|
type Multiplexer struct {
|
|
|
|
stack.PassInitState
|
|
|
|
stack.PassInitValidate
|
|
|
|
}
|
2017-06-29 12:21:57 -07:00
|
|
|
|
2017-07-30 14:51:57 -07:00
|
|
|
// Name of the module - fulfills Middleware interface
|
|
|
|
func (Multiplexer) Name() string {
|
|
|
|
return NameMultiplexer
|
|
|
|
}
|
2017-06-29 12:21:57 -07:00
|
|
|
|
2017-07-30 14:51:57 -07:00
|
|
|
var _ stack.Middleware = Multiplexer{}
|
2017-06-29 12:21:57 -07:00
|
|
|
|
2017-07-30 14:51:57 -07:00
|
|
|
// CheckTx splits the input tx and checks them all - fulfills Middlware interface
|
2017-08-21 14:13:58 -07:00
|
|
|
func (Multiplexer) CheckTx(ctx sdk.Context, store state.SimpleDB, tx sdk.Tx, next sdk.Checker) (res sdk.CheckResult, err error) {
|
2017-08-03 12:40:45 -07:00
|
|
|
if mtx, ok := tx.Unwrap().(MultiTx); ok {
|
2017-07-30 14:51:57 -07:00
|
|
|
return runAllChecks(ctx, store, mtx.Txs, next)
|
|
|
|
}
|
|
|
|
return next.CheckTx(ctx, store, tx)
|
|
|
|
}
|
2017-06-29 12:21:57 -07:00
|
|
|
|
2017-07-30 14:51:57 -07:00
|
|
|
// DeliverTx splits the input tx and checks them all - fulfills Middlware interface
|
2017-08-21 14:13:58 -07:00
|
|
|
func (Multiplexer) DeliverTx(ctx sdk.Context, store state.SimpleDB, tx sdk.Tx, next sdk.Deliver) (res sdk.DeliverResult, err error) {
|
2017-08-03 12:40:45 -07:00
|
|
|
if mtx, ok := tx.Unwrap().(MultiTx); ok {
|
2017-07-30 14:51:57 -07:00
|
|
|
return runAllDelivers(ctx, store, mtx.Txs, next)
|
|
|
|
}
|
|
|
|
return next.DeliverTx(ctx, store, tx)
|
|
|
|
}
|
2017-06-29 12:21:57 -07:00
|
|
|
|
2017-08-21 14:13:58 -07:00
|
|
|
func runAllChecks(ctx sdk.Context, store state.SimpleDB, txs []sdk.Tx, next sdk.Checker) (res sdk.CheckResult, err error) {
|
2017-07-30 14:51:57 -07:00
|
|
|
// store all results, unless anything errors
|
2017-08-21 14:13:58 -07:00
|
|
|
rs := make([]sdk.CheckResult, len(txs))
|
2017-07-30 14:51:57 -07:00
|
|
|
for i, stx := range txs {
|
|
|
|
rs[i], err = next.CheckTx(ctx, store, stx)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// now combine the results into one...
|
|
|
|
return combineChecks(rs), nil
|
|
|
|
}
|
2017-06-29 12:21:57 -07:00
|
|
|
|
2017-08-21 14:13:58 -07:00
|
|
|
func runAllDelivers(ctx sdk.Context, store state.SimpleDB, txs []sdk.Tx, next sdk.Deliver) (res sdk.DeliverResult, err error) {
|
2017-07-30 14:51:57 -07:00
|
|
|
// store all results, unless anything errors
|
2017-08-21 14:13:58 -07:00
|
|
|
rs := make([]sdk.DeliverResult, len(txs))
|
2017-07-30 14:51:57 -07:00
|
|
|
for i, stx := range txs {
|
|
|
|
rs[i], err = next.DeliverTx(ctx, store, stx)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// now combine the results into one...
|
|
|
|
return combineDelivers(rs), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// combines all data bytes as a go-wire array.
|
|
|
|
// joins all log messages with \n
|
2017-08-21 14:13:58 -07:00
|
|
|
func combineChecks(all []sdk.CheckResult) sdk.CheckResult {
|
2017-07-30 14:51:57 -07:00
|
|
|
datas := make([]data.Bytes, len(all))
|
|
|
|
logs := make([]string, len(all))
|
2017-08-04 05:11:01 -07:00
|
|
|
var allocated, payments uint64
|
2017-07-30 14:51:57 -07:00
|
|
|
for i, r := range all {
|
|
|
|
datas[i] = r.Data
|
|
|
|
logs[i] = r.Log
|
|
|
|
allocated += r.GasAllocated
|
|
|
|
payments += r.GasPayment
|
|
|
|
}
|
2017-08-21 14:13:58 -07:00
|
|
|
return sdk.CheckResult{
|
2017-07-30 14:51:57 -07:00
|
|
|
Data: wire.BinaryBytes(datas),
|
|
|
|
Log: strings.Join(logs, "\n"),
|
|
|
|
GasAllocated: allocated,
|
|
|
|
GasPayment: payments,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// combines all data bytes as a go-wire array.
|
|
|
|
// joins all log messages with \n
|
2017-08-21 14:13:58 -07:00
|
|
|
func combineDelivers(all []sdk.DeliverResult) sdk.DeliverResult {
|
2017-07-30 14:51:57 -07:00
|
|
|
datas := make([]data.Bytes, len(all))
|
|
|
|
logs := make([]string, len(all))
|
2017-08-04 05:11:01 -07:00
|
|
|
var used uint64
|
2017-07-30 14:51:57 -07:00
|
|
|
var diffs []*abci.Validator
|
|
|
|
for i, r := range all {
|
|
|
|
datas[i] = r.Data
|
|
|
|
logs[i] = r.Log
|
|
|
|
used += r.GasUsed
|
|
|
|
if len(r.Diff) > 0 {
|
|
|
|
diffs = append(diffs, r.Diff...)
|
|
|
|
}
|
|
|
|
}
|
2017-08-21 14:13:58 -07:00
|
|
|
return sdk.DeliverResult{
|
2017-07-30 14:51:57 -07:00
|
|
|
Data: wire.BinaryBytes(datas),
|
|
|
|
Log: strings.Join(logs, "\n"),
|
|
|
|
GasUsed: used,
|
|
|
|
Diff: diffs,
|
|
|
|
}
|
|
|
|
}
|