Handlers and middlewares add gas prices

This commit is contained in:
Ethan Frey 2017-08-03 19:27:06 +02:00
parent 70fe2444ab
commit 1715c0aeba
7 changed files with 74 additions and 12 deletions

26
TODO.md
View File

@ -1,6 +1,28 @@
# TODO for rewrite # TODO for rewrite
* FeeTx and CheckTx changes logic to estimate, not validate
* Add tests for new CheckTx * Add tests for new CheckTx
* Test EndBlock validator set changes
* Test Multiplexer * Test Multiplexer
Alexis:
* merkle - proof (non-existence - maybe range)
* intro to light-client and proofs
light-client proofs:
* make this sensible -> very tied to merkle proofs and API
* support new proof types
* abci add range suppprt
* merkle - api cleanup (also Bonsai)
* later: C bindings (to Bonsai?)
* crypto-ledger (while ethan gone)
light-client provider:
* caching checkpoint on Verify
* cleanup (trim old node)

View File

@ -95,6 +95,15 @@ type CheckResult struct {
GasPayment uint GasPayment uint
} }
// NewCheck sets the gas used and the response data but no more info
// these are the most common info needed to be set by the Handler
func NewCheck(gasAllocated uint, log string) CheckResult {
return CheckResult{
GasAllocated: gasAllocated,
Log: log,
}
}
var _ Dataer = CheckResult{} var _ Dataer = CheckResult{}
func (r CheckResult) ToABCI() abci.Result { func (r CheckResult) ToABCI() abci.Result {

View File

@ -12,8 +12,14 @@ import (
"github.com/tendermint/basecoin/state" "github.com/tendermint/basecoin/state"
) )
//NameCoin - name space of the coin module const (
const NameCoin = "coin" //NameCoin - name space of the coin module
NameCoin = "coin"
// CostSend is GasAllocation per input/output
CostSend = 10
// CostCredit is GasAllocation of a credit allocation
CostCredit = 20
)
// Handler includes an accountant // Handler includes an accountant
type Handler struct { type Handler struct {
@ -46,9 +52,12 @@ func (h Handler) CheckTx(ctx basecoin.Context, store state.SimpleDB,
switch t := tx.Unwrap().(type) { switch t := tx.Unwrap().(type) {
case SendTx: case SendTx:
return res, h.checkSendTx(ctx, store, t) // price based on inputs and outputs
used := uint(len(t.Inputs) + len(t.Outputs))
return basecoin.NewCheck(used*CostSend, ""), h.checkSendTx(ctx, store, t)
case CreditTx: case CreditTx:
return res, h.creditTx(ctx, store, t) // default price of 20, constant work
return basecoin.NewCheck(CostCredit, ""), h.creditTx(ctx, store, t)
} }
return res, errors.ErrUnknownTxType(tx.Unwrap()) return res, errors.ErrUnknownTxType(tx.Unwrap())
} }

View File

@ -55,15 +55,24 @@ func (h SimpleFeeMiddleware) CheckTx(ctx basecoin.Context, store state.SimpleDB,
return res, err return res, err
} }
var paid, used uint
if !fee.Fee.IsZero() { // now, try to make a IPC call to coins... if !fee.Fee.IsZero() { // now, try to make a IPC call to coins...
send := coin.NewSendOneTx(fee.Payer, h.Collector, coin.Coins{fee.Fee}) send := coin.NewSendOneTx(fee.Payer, h.Collector, coin.Coins{fee.Fee})
_, err = next.CheckTx(ctx, store, send) sendRes, err := next.CheckTx(ctx, store, send)
if err != nil { if err != nil {
return res, err return res, err
} }
paid = uint(fee.Fee.Amount)
used = sendRes.GasAllocated
} }
return next.CheckTx(ctx, store, fee.Tx) res, err = next.CheckTx(ctx, store, fee.Tx)
// add the given fee to the price for gas, plus one query
if err == nil {
res.GasPayment += paid
res.GasAllocated += used
}
return res, err
} }
// DeliverTx - send the fee handler transaction // DeliverTx - send the fee handler transaction

View File

@ -9,6 +9,7 @@ import (
//nolint //nolint
const ( const (
NameNonce = "nonce" NameNonce = "nonce"
CostNonce = 10
) )
// ReplayCheck uses the sequence to check for replay attacks // ReplayCheck uses the sequence to check for replay attacks
@ -33,7 +34,9 @@ func (r ReplayCheck) CheckTx(ctx basecoin.Context, store state.SimpleDB,
return res, err return res, err
} }
return next.CheckTx(ctx, store, stx) res, err = next.CheckTx(ctx, store, stx)
res.GasAllocated += CostNonce
return res, err
} }
// DeliverTx verifies tx is not being replayed - fulfills Middlware interface // DeliverTx verifies tx is not being replayed - fulfills Middlware interface

View File

@ -6,8 +6,14 @@ import (
"github.com/tendermint/basecoin/state" "github.com/tendermint/basecoin/state"
) )
//NameRole - name space of the roles module const (
const NameRole = "role" //NameRole - name space of the roles module
NameRole = "role"
// CostCreate is the cost to create a new role
CostCreate = 40
// CostAssume is the cost to assume a role as part of a tx
CostAssume = 5
)
// Handler allows us to create new roles // Handler allows us to create new roles
type Handler struct { type Handler struct {
@ -34,6 +40,7 @@ func (h Handler) CheckTx(ctx basecoin.Context, store state.SimpleDB, tx basecoin
if err != nil { if err != nil {
return return
} }
res = basecoin.NewCheck(CostCreate, "")
err = checkNoRole(store, cr.Role) err = checkNoRole(store, cr.Role)
return return
} }

View File

@ -41,7 +41,10 @@ func (m Middleware) CheckTx(ctx basecoin.Context, store state.SimpleDB, tx basec
} }
// one could add multiple role statements, repeat as needed // one could add multiple role statements, repeat as needed
return m.CheckTx(ctx, store, assume.Tx, next) // charging for each level
res, err = m.CheckTx(ctx, store, assume.Tx, next)
res.GasAllocated += CostAssume
return
} }
// DeliverTx tries to assume the named role if requested. // DeliverTx tries to assume the named role if requested.