Merge PR #3447: Consume Gas Proportional to Tx Size
This commit is contained in:
parent
3780b84290
commit
082295172e
|
@ -58,6 +58,8 @@ IMPROVEMENTS
|
|||
* [\#3418](https://github.com/cosmos/cosmos-sdk/issues/3418) Add vesting account
|
||||
genesis validation checks to `GaiaValidateGenesisState`.
|
||||
* [\#3420](https://github.com/cosmos/cosmos-sdk/issues/3420) Added maximum length to governance proposal descriptions and titles
|
||||
* [\#3256](https://github.com/cosmos/cosmos-sdk/issues/3256) Add gas consumption
|
||||
for tx size in the ante handler.
|
||||
* [\#3454](https://github.com/cosmos/cosmos-sdk/pull/3454) Add `--jail-whitelist` to `gaiad export` to enable testing of complex exports
|
||||
* [\#3424](https://github.com/cosmos/cosmos-sdk/issues/3424) Allow generation of gentxs with empty memo field.
|
||||
|
||||
|
|
|
@ -390,7 +390,7 @@ func handleQueryApp(app *BaseApp, path []string, req abci.RequestQuery) (res abc
|
|||
if err != nil {
|
||||
result = err.Result()
|
||||
} else {
|
||||
result = app.Simulate(tx)
|
||||
result = app.Simulate(txBytes, tx)
|
||||
}
|
||||
case "version":
|
||||
return abci.ResponseQuery{
|
||||
|
@ -718,7 +718,10 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte, tx sdk.Tx) (result sdk
|
|||
if r := recover(); r != nil {
|
||||
switch rType := r.(type) {
|
||||
case sdk.ErrorOutOfGas:
|
||||
log := fmt.Sprintf("out of gas in location: %v", rType.Descriptor)
|
||||
log := fmt.Sprintf(
|
||||
"out of gas in location: %v; gasWanted: %d, gasUsed: %d",
|
||||
rType.Descriptor, gasWanted, ctx.GasMeter().GasConsumed(),
|
||||
)
|
||||
result = sdk.ErrOutOfGas(log).Result()
|
||||
default:
|
||||
log := fmt.Sprintf("recovered: %v\nstack:\n%v", r, string(debug.Stack()))
|
||||
|
|
|
@ -655,20 +655,20 @@ func TestSimulateTx(t *testing.T) {
|
|||
app.BeginBlock(abci.RequestBeginBlock{})
|
||||
|
||||
tx := newTxCounter(count, count)
|
||||
txBytes, err := cdc.MarshalBinaryLengthPrefixed(tx)
|
||||
require.Nil(t, err)
|
||||
|
||||
// simulate a message, check gas reported
|
||||
result := app.Simulate(tx)
|
||||
result := app.Simulate(txBytes, tx)
|
||||
require.True(t, result.IsOK(), result.Log)
|
||||
require.Equal(t, gasConsumed, result.GasUsed)
|
||||
|
||||
// simulate again, same result
|
||||
result = app.Simulate(tx)
|
||||
result = app.Simulate(txBytes, tx)
|
||||
require.True(t, result.IsOK(), result.Log)
|
||||
require.Equal(t, gasConsumed, result.GasUsed)
|
||||
|
||||
// simulate by calling Query with encoded tx
|
||||
txBytes, err := cdc.MarshalBinaryLengthPrefixed(tx)
|
||||
require.Nil(t, err)
|
||||
query := abci.RequestQuery{
|
||||
Path: "/app/simulate",
|
||||
Data: txBytes,
|
||||
|
|
|
@ -14,8 +14,8 @@ func (app *BaseApp) Check(tx sdk.Tx) (result sdk.Result) {
|
|||
}
|
||||
|
||||
// nolint - full tx execution
|
||||
func (app *BaseApp) Simulate(tx sdk.Tx) (result sdk.Result) {
|
||||
return app.runTx(runTxModeSimulate, nil, tx)
|
||||
func (app *BaseApp) Simulate(txBytes []byte, tx sdk.Tx) (result sdk.Result) {
|
||||
return app.runTx(runTxModeSimulate, txBytes, tx)
|
||||
}
|
||||
|
||||
// nolint
|
||||
|
|
|
@ -11,9 +11,9 @@ import (
|
|||
|
||||
// nolint
|
||||
const (
|
||||
// DefaultGasAdjustment is applied to gas estimates to avoid tx
|
||||
// execution failures due to state changes that might
|
||||
// occur between the tx simulation and the actual run.
|
||||
// DefaultGasAdjustment is applied to gas estimates to avoid tx execution
|
||||
// failures due to state changes that might occur between the tx simulation
|
||||
// and the actual run.
|
||||
DefaultGasAdjustment = 1.0
|
||||
DefaultGasLimit = 200000
|
||||
GasFlagAuto = "auto"
|
||||
|
|
|
@ -209,7 +209,9 @@ func TestCoinSend(t *testing.T) {
|
|||
require.Equal(t, http.StatusInternalServerError, res.StatusCode, body)
|
||||
|
||||
// run simulation and test success with estimated gas
|
||||
res, body, _ = doTransferWithGas(t, port, seed, name1, memo, pw, addr, "10000", 1.0, true, false, fees)
|
||||
res, body, _ = doTransferWithGas(
|
||||
t, port, seed, name1, memo, pw, addr, "10000", 1.0, true, false, fees,
|
||||
)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
|
||||
var gasEstResp rest.GasEstimateResponse
|
||||
|
@ -285,7 +287,9 @@ func TestCoinSendGenerateSignAndBroadcast(t *testing.T) {
|
|||
acc := getAccount(t, port, addr)
|
||||
|
||||
// simulate tx
|
||||
res, body, _ := doTransferWithGas(t, port, seed, name1, memo, "", addr, client.GasFlagAuto, 1, true, false, fees)
|
||||
res, body, _ := doTransferWithGas(
|
||||
t, port, seed, name1, memo, "", addr, client.GasFlagAuto, 1.0, true, false, fees,
|
||||
)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
|
||||
var gasEstResp rest.GasEstimateResponse
|
||||
|
|
|
@ -19,6 +19,15 @@ import (
|
|||
authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder"
|
||||
)
|
||||
|
||||
// GasEstimateResponse defines a response definition for tx gas estimation.
|
||||
type GasEstimateResponse struct {
|
||||
GasEstimate uint64 `json:"gas_estimate"`
|
||||
}
|
||||
|
||||
func (gr GasEstimateResponse) String() string {
|
||||
return fmt.Sprintf("gas estimate: %d", gr.GasEstimate)
|
||||
}
|
||||
|
||||
// CompleteAndBroadcastTxCLI implements a utility function that facilitates
|
||||
// sending a series of messages in a signed transaction given a TxBuilder and a
|
||||
// QueryContext. It ensures that the account exists, has a proper number and
|
||||
|
@ -39,8 +48,11 @@ func CompleteAndBroadcastTxCLI(txBldr authtxb.TxBuilder, cliCtx context.CLIConte
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "estimated gas = %v\n", txBldr.GetGas())
|
||||
|
||||
gasEst := GasEstimateResponse{GasEstimate: txBldr.GetGas()}
|
||||
fmt.Fprintf(os.Stderr, gasEst.String())
|
||||
}
|
||||
|
||||
if cliCtx.Simulate {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ func appStateFromGenesisFileFn(r *rand.Rand, accs []simulation.Account, genesisT
|
|||
privKey := secp256k1.GenPrivKeySecp256k1(privkeySeed)
|
||||
newAccs = append(newAccs, simulation.Account{privKey, privKey.PubKey(), acc.Address})
|
||||
}
|
||||
return json.RawMessage(genesis.AppState), newAccs, genesis.ChainID
|
||||
return genesis.AppState, newAccs, genesis.ChainID
|
||||
}
|
||||
|
||||
func appStateRandomizedFn(r *rand.Rand, accs []simulation.Account, genesisTimestamp time.Time) (json.RawMessage, []simulation.Account, string) {
|
||||
|
@ -138,11 +138,11 @@ func appStateRandomizedFn(r *rand.Rand, accs []simulation.Account, genesisTimest
|
|||
|
||||
authGenesis := auth.GenesisState{
|
||||
Params: auth.Params{
|
||||
MemoCostPerByte: uint64(r.Intn(10) + 1),
|
||||
MaxMemoCharacters: uint64(r.Intn(200-100) + 100),
|
||||
MaxMemoCharacters: uint64(randIntBetween(r, 100, 200)),
|
||||
TxSigLimit: uint64(r.Intn(7) + 1),
|
||||
SigVerifyCostED25519: uint64(r.Intn(1000-500) + 500),
|
||||
SigVerifyCostSecp256k1: uint64(r.Intn(1000-500) + 500),
|
||||
TxSizeCostPerByte: uint64(randIntBetween(r, 5, 15)),
|
||||
SigVerifyCostED25519: uint64(randIntBetween(r, 500, 1000)),
|
||||
SigVerifyCostSecp256k1: uint64(randIntBetween(r, 500, 1000)),
|
||||
},
|
||||
}
|
||||
fmt.Printf("Selected randomly generated auth parameters:\n\t%+v\n", authGenesis)
|
||||
|
|
|
@ -279,7 +279,7 @@ func TestGaiaCLIGasAuto(t *testing.T) {
|
|||
}{}
|
||||
err := cdc.UnmarshalJSON([]byte(stdout), &sendResp)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, sendResp.Response.GasWanted, sendResp.Response.GasUsed)
|
||||
require.True(t, sendResp.Response.GasWanted >= sendResp.Response.GasUsed)
|
||||
tests.WaitForNextNBlocksTM(1, f.Port)
|
||||
|
||||
// Check state has changed accordingly
|
||||
|
@ -690,7 +690,7 @@ func TestGaiaCLISendGenerateSignAndBroadcast(t *testing.T) {
|
|||
|
||||
// Unmarshal the response and ensure that gas was properly used
|
||||
require.Nil(t, app.MakeCodec().UnmarshalJSON([]byte(stdout), &result))
|
||||
require.Equal(t, msg.Fee.Gas, uint64(result.Response.GasUsed))
|
||||
require.True(t, msg.Fee.Gas >= uint64(result.Response.GasUsed))
|
||||
require.Equal(t, msg.Fee.Gas, uint64(result.Response.GasWanted))
|
||||
tests.WaitForNextNBlocksTM(1, f.Port)
|
||||
|
||||
|
|
|
@ -7,9 +7,11 @@ general purpose censorship of transactions of little economic value. Fees
|
|||
are best suited as an anti-spam mechanism where validators are disinterested in
|
||||
the use of the network and identities of users.
|
||||
|
||||
Fees are determined by the gas limits and gas prices transactions provide.
|
||||
Operators should set minimum gas prices when starting their nodes. They must set
|
||||
the unit costs of gas in each token denomination they wish to support:
|
||||
Fees are determined by the gas limits and gas prices transactions provide, where
|
||||
`fees = ceil(gasLimit * gasPrices)`. Txs incur gas costs for all state reads/writes,
|
||||
signature verification, as well as costs proportional to the tx size. Operators
|
||||
should set minimum gas prices when starting their nodes. They must set the unit
|
||||
costs of gas in each token denomination they wish to support:
|
||||
|
||||
`gaiad start ... --minimum-gas-prices=0.00001steak,0.05photinos`
|
||||
|
||||
|
|
|
@ -15,6 +15,17 @@ import (
|
|||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
var (
|
||||
// simulation signature values used to estimate gas consumption
|
||||
simSecp256k1Pubkey secp256k1.PubKeySecp256k1
|
||||
simSecp256k1Sig [64]byte
|
||||
)
|
||||
|
||||
func init() {
|
||||
bz, _ := hex.DecodeString("035AD6810A47F073553FF30D2FCC7E0D3B1C0B74B61A1AAA2582344037151E143A")
|
||||
copy(simSecp256k1Pubkey[:], bz)
|
||||
}
|
||||
|
||||
// NewAnteHandler returns an AnteHandler that checks and increments sequence
|
||||
// numbers, checks signatures & account numbers, and deducts fees from the first
|
||||
// signer.
|
||||
|
@ -54,8 +65,12 @@ func NewAnteHandler(ak AccountKeeper, fck FeeCollectionKeeper) sdk.AnteHandler {
|
|||
if r := recover(); r != nil {
|
||||
switch rType := r.(type) {
|
||||
case sdk.ErrorOutOfGas:
|
||||
log := fmt.Sprintf("out of gas in location: %v", rType.Descriptor)
|
||||
log := fmt.Sprintf(
|
||||
"out of gas in location: %v; gasWanted: %d, gasUsed: %d",
|
||||
rType.Descriptor, stdTx.Fee.Gas, newCtx.GasMeter().GasConsumed(),
|
||||
)
|
||||
res = sdk.ErrOutOfGas(log).Result()
|
||||
|
||||
res.GasWanted = stdTx.Fee.Gas
|
||||
res.GasUsed = newCtx.GasMeter().GasConsumed()
|
||||
abort = true
|
||||
|
@ -69,7 +84,9 @@ func NewAnteHandler(ak AccountKeeper, fck FeeCollectionKeeper) sdk.AnteHandler {
|
|||
return newCtx, err.Result(), true
|
||||
}
|
||||
|
||||
if res := ValidateMemo(newCtx.GasMeter(), stdTx, params); !res.IsOK() {
|
||||
newCtx.GasMeter().ConsumeGas(params.TxSizeCostPerByte*sdk.Gas(len(newCtx.TxBytes())), "txSize")
|
||||
|
||||
if res := ValidateMemo(stdTx, params); !res.IsOK() {
|
||||
return newCtx, res, true
|
||||
}
|
||||
|
||||
|
@ -131,9 +148,8 @@ func GetSignerAcc(ctx sdk.Context, ak AccountKeeper, addr sdk.AccAddress) (Accou
|
|||
return nil, sdk.ErrUnknownAddress(addr.String()).Result()
|
||||
}
|
||||
|
||||
// ValidateMemo validates the memo and if successful consumes gas for
|
||||
// verification.
|
||||
func ValidateMemo(gasMeter sdk.GasMeter, stdTx StdTx, params Params) sdk.Result {
|
||||
// ValidateMemo validates the memo size.
|
||||
func ValidateMemo(stdTx StdTx, params Params) sdk.Result {
|
||||
memoLength := len(stdTx.GetMemo())
|
||||
if uint64(memoLength) > params.MaxMemoCharacters {
|
||||
return sdk.ErrMemoTooLarge(
|
||||
|
@ -144,7 +160,6 @@ func ValidateMemo(gasMeter sdk.GasMeter, stdTx StdTx, params Params) sdk.Result
|
|||
).Result()
|
||||
}
|
||||
|
||||
gasMeter.ConsumeGas(params.MemoCostPerByte*sdk.Gas(memoLength), "memo")
|
||||
return sdk.Result{}
|
||||
}
|
||||
|
||||
|
@ -164,7 +179,15 @@ func processSig(
|
|||
return nil, sdk.ErrInternal("setting PubKey on signer's account").Result()
|
||||
}
|
||||
|
||||
consumeSignatureVerificationGas(ctx.GasMeter(), sig.Signature, pubKey, params)
|
||||
if simulate {
|
||||
// Simulated txs should not contain a signature and are not required to
|
||||
// contain a pubkey, so we must account for tx size of including a
|
||||
// StdSignature (Amino encoding) and simulate gas consumption
|
||||
// (assuming a SECP256k1 simulation key).
|
||||
consumeSimSigGas(ctx.GasMeter(), pubKey, sig, params)
|
||||
}
|
||||
|
||||
consumeSigVerificationGas(ctx.GasMeter(), sig.Signature, pubKey, params)
|
||||
if !simulate && !pubKey.VerifyBytes(signBytes, sig.Signature) {
|
||||
return nil, sdk.ErrUnauthorized("signature verification failed").Result()
|
||||
}
|
||||
|
@ -178,11 +201,22 @@ func processSig(
|
|||
return acc, res
|
||||
}
|
||||
|
||||
var dummySecp256k1Pubkey secp256k1.PubKeySecp256k1
|
||||
func consumeSimSigGas(gasmeter sdk.GasMeter, pubkey crypto.PubKey, sig StdSignature, params Params) {
|
||||
simSig := StdSignature{PubKey: pubkey}
|
||||
if len(sig.Signature) == 0 {
|
||||
simSig.Signature = simSecp256k1Sig[:]
|
||||
}
|
||||
|
||||
func init() {
|
||||
bz, _ := hex.DecodeString("035AD6810A47F073553FF30D2FCC7E0D3B1C0B74B61A1AAA2582344037151E143A")
|
||||
copy(dummySecp256k1Pubkey[:], bz)
|
||||
sigBz := msgCdc.MustMarshalBinaryLengthPrefixed(simSig)
|
||||
cost := sdk.Gas(len(sigBz) + 6)
|
||||
|
||||
// If the pubkey is a multi-signature pubkey, then we estimate for the maximum
|
||||
// number of signers.
|
||||
if _, ok := pubkey.(multisig.PubKeyMultisigThreshold); ok {
|
||||
cost *= params.TxSigLimit
|
||||
}
|
||||
|
||||
gasmeter.ConsumeGas(params.TxSizeCostPerByte*cost, "txSize")
|
||||
}
|
||||
|
||||
// ProcessPubKey verifies that the given account address matches that of the
|
||||
|
@ -197,7 +231,7 @@ func ProcessPubKey(acc Account, sig StdSignature, simulate bool) (crypto.PubKey,
|
|||
// shall consume the largest amount, i.e. it takes more gas to verify
|
||||
// secp256k1 keys than ed25519 ones.
|
||||
if pubKey == nil {
|
||||
return dummySecp256k1Pubkey, sdk.Result{}
|
||||
return simSecp256k1Pubkey, sdk.Result{}
|
||||
}
|
||||
|
||||
return pubKey, sdk.Result{}
|
||||
|
@ -218,25 +252,27 @@ func ProcessPubKey(acc Account, sig StdSignature, simulate bool) (crypto.PubKey,
|
|||
return pubKey, sdk.Result{}
|
||||
}
|
||||
|
||||
// consumeSignatureVerificationGas consumes gas for signature verification based
|
||||
// upon the public key type. The cost is fetched from the given params and is
|
||||
// matched by the concrete type.
|
||||
// consumeSigVerificationGas consumes gas for signature verification based upon
|
||||
// the public key type. The cost is fetched from the given params and is matched
|
||||
// by the concrete type.
|
||||
//
|
||||
// TODO: Design a cleaner and flexible way to match concrete public key types.
|
||||
func consumeSignatureVerificationGas(meter sdk.GasMeter, sig []byte, pubkey crypto.PubKey, params Params) {
|
||||
func consumeSigVerificationGas(meter sdk.GasMeter, sig []byte, pubkey crypto.PubKey, params Params) {
|
||||
pubkeyType := strings.ToLower(fmt.Sprintf("%T", pubkey))
|
||||
switch {
|
||||
case strings.Contains(pubkeyType, "ed25519"):
|
||||
meter.ConsumeGas(params.SigVerifyCostED25519, "ante verify: ed25519")
|
||||
|
||||
case strings.Contains(pubkeyType, "secp256k1"):
|
||||
meter.ConsumeGas(params.SigVerifyCostSecp256k1, "ante verify: secp256k1")
|
||||
case strings.Contains(pubkeyType, "multisigthreshold"):
|
||||
|
||||
case strings.Contains(pubkeyType, "multisigthreshold"):
|
||||
var multisignature multisig.Multisignature
|
||||
codec.Cdc.MustUnmarshalBinaryBare(sig, &multisignature)
|
||||
multisigPubKey := pubkey.(multisig.PubKeyMultisigThreshold)
|
||||
|
||||
multisigPubKey := pubkey.(multisig.PubKeyMultisigThreshold)
|
||||
consumeMultisignatureVerificationGas(meter, multisignature, multisigPubKey, params)
|
||||
|
||||
default:
|
||||
panic(fmt.Sprintf("unrecognized signature type: %s", pubkeyType))
|
||||
}
|
||||
|
@ -250,7 +286,7 @@ func consumeMultisignatureVerificationGas(meter sdk.GasMeter,
|
|||
sigIndex := 0
|
||||
for i := 0; i < size; i++ {
|
||||
if sig.BitArray.GetIndex(i) {
|
||||
consumeSignatureVerificationGas(meter, sig.Sigs[sigIndex], pubkey.PubKeys[i], params)
|
||||
consumeSigVerificationGas(meter, sig.Sigs[sigIndex], pubkey.PubKeys[i], params)
|
||||
sigIndex++
|
||||
}
|
||||
}
|
||||
|
@ -294,8 +330,6 @@ func DeductFees(blockTime time.Time, acc Account, fee StdFee) (Account, sdk.Resu
|
|||
// enough fees to cover a proposer's minimum fees. An result object is returned
|
||||
// indicating success or failure.
|
||||
//
|
||||
// TODO: Account for transaction size.
|
||||
//
|
||||
// Contract: This should only be called during CheckTx as it cannot be part of
|
||||
// consensus.
|
||||
func EnsureSufficientMempoolFees(ctx sdk.Context, stdFee StdFee) sdk.Result {
|
||||
|
|
|
@ -595,9 +595,9 @@ func TestConsumeSignatureVerificationGas(t *testing.T) {
|
|||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.wantPanic {
|
||||
require.Panics(t, func() { consumeSignatureVerificationGas(tt.args.meter, tt.args.sig, tt.args.pubkey, tt.args.params) })
|
||||
require.Panics(t, func() { consumeSigVerificationGas(tt.args.meter, tt.args.sig, tt.args.pubkey, tt.args.params) })
|
||||
} else {
|
||||
consumeSignatureVerificationGas(tt.args.meter, tt.args.sig, tt.args.pubkey, tt.args.params)
|
||||
consumeSigVerificationGas(tt.args.meter, tt.args.sig, tt.args.pubkey, tt.args.params)
|
||||
require.Equal(t, tt.gasConsumed, tt.args.meter.GasConsumed(), fmt.Sprintf("%d != %d", tt.gasConsumed, tt.args.meter.GasConsumed()))
|
||||
}
|
||||
})
|
||||
|
|
|
@ -54,8 +54,8 @@ func ValidateGenesis(data GenesisState) error {
|
|||
if data.Params.MaxMemoCharacters == 0 {
|
||||
return fmt.Errorf("invalid max memo characters: %d", data.Params.MaxMemoCharacters)
|
||||
}
|
||||
if data.Params.MemoCostPerByte == 0 {
|
||||
return fmt.Errorf("invalid memo cost per byte: %d", data.Params.MemoCostPerByte)
|
||||
if data.Params.TxSizeCostPerByte == 0 {
|
||||
return fmt.Errorf("invalid tx size cost per byte: %d", data.Params.TxSizeCostPerByte)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/params"
|
||||
)
|
||||
|
||||
|
@ -15,18 +14,18 @@ const DefaultParamspace = "auth"
|
|||
|
||||
// Default parameter values
|
||||
const (
|
||||
DefaultMemoCostPerByte sdk.Gas = 3
|
||||
DefaultMaxMemoCharacters uint64 = 256
|
||||
DefaultTxSigLimit uint64 = 7
|
||||
DefaultSigVerifyCostED25519 uint64 = 590
|
||||
DefaultSigVerifyCostSecp256k1 uint64 = 1000
|
||||
DefaultMaxMemoCharacters uint64 = 256
|
||||
DefaultTxSigLimit uint64 = 7
|
||||
DefaultTxSizeCostPerByte uint64 = 10
|
||||
DefaultSigVerifyCostED25519 uint64 = 590
|
||||
DefaultSigVerifyCostSecp256k1 uint64 = 1000
|
||||
)
|
||||
|
||||
// Parameter keys
|
||||
var (
|
||||
KeyMemoCostPerByte = []byte("MemoCostPerByte")
|
||||
KeyMaxMemoCharacters = []byte("MaxMemoCharacters")
|
||||
KeyTxSigLimit = []byte("TxSigLimit")
|
||||
KeyTxSizeCostPerByte = []byte("TxSizeCostPerByte")
|
||||
KeySigVerifyCostED25519 = []byte("SigVerifyCostED25519")
|
||||
KeySigVerifyCostSecp256k1 = []byte("SigVerifyCostSecp256k1")
|
||||
)
|
||||
|
@ -35,9 +34,9 @@ var _ params.ParamSet = &Params{}
|
|||
|
||||
// Params defines the parameters for the auth module.
|
||||
type Params struct {
|
||||
MemoCostPerByte sdk.Gas
|
||||
MaxMemoCharacters uint64
|
||||
TxSigLimit uint64 // max total number of signatures per tx
|
||||
TxSizeCostPerByte uint64
|
||||
SigVerifyCostED25519 uint64
|
||||
SigVerifyCostSecp256k1 uint64
|
||||
}
|
||||
|
@ -52,9 +51,9 @@ func ParamTypeTable() params.TypeTable {
|
|||
// nolint
|
||||
func (p *Params) KeyValuePairs() params.KeyValuePairs {
|
||||
return params.KeyValuePairs{
|
||||
{KeyMemoCostPerByte, &p.MemoCostPerByte},
|
||||
{KeyMaxMemoCharacters, &p.MaxMemoCharacters},
|
||||
{KeyTxSigLimit, &p.TxSigLimit},
|
||||
{KeyTxSizeCostPerByte, &p.TxSizeCostPerByte},
|
||||
{KeySigVerifyCostED25519, &p.SigVerifyCostED25519},
|
||||
{KeySigVerifyCostSecp256k1, &p.SigVerifyCostSecp256k1},
|
||||
}
|
||||
|
@ -70,9 +69,9 @@ func (p Params) Equal(p2 Params) bool {
|
|||
// DefaultParams returns a default set of parameters.
|
||||
func DefaultParams() Params {
|
||||
return Params{
|
||||
MemoCostPerByte: DefaultMemoCostPerByte,
|
||||
MaxMemoCharacters: DefaultMaxMemoCharacters,
|
||||
TxSigLimit: DefaultTxSigLimit,
|
||||
TxSizeCostPerByte: DefaultTxSizeCostPerByte,
|
||||
SigVerifyCostED25519: DefaultSigVerifyCostED25519,
|
||||
SigVerifyCostSecp256k1: DefaultSigVerifyCostSecp256k1,
|
||||
}
|
||||
|
@ -83,9 +82,9 @@ func (p Params) String() string {
|
|||
var sb strings.Builder
|
||||
|
||||
sb.WriteString("Params: \n")
|
||||
sb.WriteString(fmt.Sprintf("MemoCostPerByte: %v\n", p.MemoCostPerByte))
|
||||
sb.WriteString(fmt.Sprintf("MaxMemoCharacters: %d\n", p.MaxMemoCharacters))
|
||||
sb.WriteString(fmt.Sprintf("TxSigLimit: %d\n", p.TxSigLimit))
|
||||
sb.WriteString(fmt.Sprintf("TxSizeCostPerByte: %d\n", p.TxSizeCostPerByte))
|
||||
sb.WriteString(fmt.Sprintf("SigVerifyCostED25519: %d\n", p.SigVerifyCostED25519))
|
||||
sb.WriteString(fmt.Sprintf("SigVerifyCostSecp256k1: %d\n", p.SigVerifyCostSecp256k1))
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@ func TestMsgSendWithAccounts(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
mock.SignCheckDeliver(t, mapp.BaseApp, tc.msgs, tc.accNums, tc.accSeqs, tc.expSimPass, tc.expPass, tc.privKeys...)
|
||||
mock.SignCheckDeliver(t, mapp.Cdc, mapp.BaseApp, tc.msgs, tc.accNums, tc.accSeqs, tc.expSimPass, tc.expPass, tc.privKeys...)
|
||||
|
||||
for _, eb := range tc.expectedBalances {
|
||||
mock.CheckBalance(t, mapp, eb.addr, eb.coins)
|
||||
|
@ -180,7 +180,7 @@ func TestMsgSendMultipleOut(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
mock.SignCheckDeliver(t, mapp.BaseApp, tc.msgs, tc.accNums, tc.accSeqs, tc.expSimPass, tc.expPass, tc.privKeys...)
|
||||
mock.SignCheckDeliver(t, mapp.Cdc, mapp.BaseApp, tc.msgs, tc.accNums, tc.accSeqs, tc.expSimPass, tc.expPass, tc.privKeys...)
|
||||
|
||||
for _, eb := range tc.expectedBalances {
|
||||
mock.CheckBalance(t, mapp, eb.addr, eb.coins)
|
||||
|
@ -224,7 +224,7 @@ func TestSengMsgMultipleInOut(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
mock.SignCheckDeliver(t, mapp.BaseApp, tc.msgs, tc.accNums, tc.accSeqs, tc.expSimPass, tc.expPass, tc.privKeys...)
|
||||
mock.SignCheckDeliver(t, mapp.Cdc, mapp.BaseApp, tc.msgs, tc.accNums, tc.accSeqs, tc.expSimPass, tc.expPass, tc.privKeys...)
|
||||
|
||||
for _, eb := range tc.expectedBalances {
|
||||
mock.CheckBalance(t, mapp, eb.addr, eb.coins)
|
||||
|
@ -269,7 +269,7 @@ func TestMsgSendDependent(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
mock.SignCheckDeliver(t, mapp.BaseApp, tc.msgs, tc.accNums, tc.accSeqs, tc.expSimPass, tc.expPass, tc.privKeys...)
|
||||
mock.SignCheckDeliver(t, mapp.Cdc, mapp.BaseApp, tc.msgs, tc.accNums, tc.accSeqs, tc.expSimPass, tc.expPass, tc.privKeys...)
|
||||
|
||||
for _, eb := range tc.expectedBalances {
|
||||
mock.CheckBalance(t, mapp, eb.addr, eb.coins)
|
||||
|
|
|
@ -72,10 +72,10 @@ func TestIBCMsgs(t *testing.T) {
|
|||
Sequence: 0,
|
||||
}
|
||||
|
||||
mock.SignCheckDeliver(t, mapp.BaseApp, []sdk.Msg{transferMsg}, []uint64{0}, []uint64{0}, true, true, priv1)
|
||||
mock.SignCheckDeliver(t, mapp.Cdc, mapp.BaseApp, []sdk.Msg{transferMsg}, []uint64{0}, []uint64{0}, true, true, priv1)
|
||||
mock.CheckBalance(t, mapp, addr1, emptyCoins)
|
||||
mock.SignCheckDeliver(t, mapp.BaseApp, []sdk.Msg{transferMsg}, []uint64{0}, []uint64{1}, false, false, priv1)
|
||||
mock.SignCheckDeliver(t, mapp.BaseApp, []sdk.Msg{receiveMsg}, []uint64{0}, []uint64{2}, true, true, priv1)
|
||||
mock.SignCheckDeliver(t, mapp.Cdc, mapp.BaseApp, []sdk.Msg{transferMsg}, []uint64{0}, []uint64{1}, false, false, priv1)
|
||||
mock.SignCheckDeliver(t, mapp.Cdc, mapp.BaseApp, []sdk.Msg{receiveMsg}, []uint64{0}, []uint64{2}, true, true, priv1)
|
||||
mock.CheckBalance(t, mapp, addr1, coins)
|
||||
mock.SignCheckDeliver(t, mapp.BaseApp, []sdk.Msg{receiveMsg}, []uint64{0}, []uint64{2}, false, false, priv1)
|
||||
mock.SignCheckDeliver(t, mapp.Cdc, mapp.BaseApp, []sdk.Msg{receiveMsg}, []uint64{0}, []uint64{2}, false, false, priv1)
|
||||
}
|
||||
|
|
|
@ -51,10 +51,7 @@ func NewApp() *App {
|
|||
db := dbm.NewMemDB()
|
||||
|
||||
// Create the cdc with some standard codecs
|
||||
cdc := codec.New()
|
||||
sdk.RegisterCodec(cdc)
|
||||
codec.RegisterCrypto(cdc)
|
||||
auth.RegisterCodec(cdc)
|
||||
cdc := createCodec()
|
||||
|
||||
// Create your application object
|
||||
app := &App{
|
||||
|
@ -337,3 +334,11 @@ func incrementAllSequenceNumbers(initSeqNums []uint64) {
|
|||
initSeqNums[i]++
|
||||
}
|
||||
}
|
||||
|
||||
func createCodec() *codec.Codec {
|
||||
cdc := codec.New()
|
||||
sdk.RegisterCodec(cdc)
|
||||
codec.RegisterCrypto(cdc)
|
||||
auth.RegisterCodec(cdc)
|
||||
return cdc
|
||||
}
|
||||
|
|
|
@ -61,14 +61,14 @@ func TestCheckAndDeliverGenTx(t *testing.T) {
|
|||
require.Equal(t, accs[0], acct.(*auth.BaseAccount))
|
||||
|
||||
SignCheckDeliver(
|
||||
t, mApp.BaseApp, []sdk.Msg{msg},
|
||||
t, mApp.Cdc, mApp.BaseApp, []sdk.Msg{msg},
|
||||
[]uint64{accs[0].GetAccountNumber()}, []uint64{accs[0].GetSequence()},
|
||||
true, true, privKeys[0],
|
||||
)
|
||||
|
||||
// Signing a tx with the wrong privKey should result in an auth error
|
||||
res := SignCheckDeliver(
|
||||
t, mApp.BaseApp, []sdk.Msg{msg},
|
||||
t, mApp.Cdc, mApp.BaseApp, []sdk.Msg{msg},
|
||||
[]uint64{accs[1].GetAccountNumber()}, []uint64{accs[1].GetSequence() + 1},
|
||||
true, false, privKeys[1],
|
||||
)
|
||||
|
@ -78,7 +78,7 @@ func TestCheckAndDeliverGenTx(t *testing.T) {
|
|||
|
||||
// Resigning the tx with the correct privKey should result in an OK result
|
||||
SignCheckDeliver(
|
||||
t, mApp.BaseApp, []sdk.Msg{msg},
|
||||
t, mApp.Cdc, mApp.BaseApp, []sdk.Msg{msg},
|
||||
[]uint64{accs[0].GetAccountNumber()}, []uint64{accs[0].GetSequence() + 1},
|
||||
true, true, privKeys[0],
|
||||
)
|
||||
|
|
|
@ -5,6 +5,8 @@ import (
|
|||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
|
@ -71,12 +73,16 @@ func CheckGenTx(
|
|||
// the parameter 'expPass' against the result. A corresponding result is
|
||||
// returned.
|
||||
func SignCheckDeliver(
|
||||
t *testing.T, app *baseapp.BaseApp, msgs []sdk.Msg, accNums []uint64,
|
||||
seq []uint64, expSimPass, expPass bool, priv ...crypto.PrivKey,
|
||||
t *testing.T, cdc *codec.Codec, app *baseapp.BaseApp, msgs []sdk.Msg,
|
||||
accNums []uint64, seq []uint64, expSimPass, expPass bool, priv ...crypto.PrivKey,
|
||||
) sdk.Result {
|
||||
tx := GenTx(msgs, accNums, seq, priv...)
|
||||
|
||||
txBytes, err := cdc.MarshalBinaryLengthPrefixed(tx)
|
||||
require.Nil(t, err)
|
||||
|
||||
// Must simulate now as CheckTx doesn't run Msgs anymore
|
||||
res := app.Simulate(tx)
|
||||
res := app.Simulate(txBytes, tx)
|
||||
|
||||
if expSimPass {
|
||||
require.Equal(t, sdk.CodeOK, res.Code, res.Log)
|
||||
|
|
|
@ -26,6 +26,8 @@ func getMockApp(t *testing.T) (*mock.App, staking.Keeper, Keeper) {
|
|||
mapp := mock.NewApp()
|
||||
|
||||
RegisterCodec(mapp.Cdc)
|
||||
stakingTypes.RegisterCodec(mapp.Cdc)
|
||||
|
||||
keyStaking := sdk.NewKVStoreKey(staking.StoreKey)
|
||||
tkeyStaking := sdk.NewTransientStoreKey(staking.TStoreKey)
|
||||
keySlashing := sdk.NewKVStoreKey(StoreKey)
|
||||
|
@ -107,7 +109,7 @@ func TestSlashingMsgs(t *testing.T) {
|
|||
createValidatorMsg := staking.NewMsgCreateValidator(
|
||||
sdk.ValAddress(addr1), priv1.PubKey(), bondCoin, description, commission,
|
||||
)
|
||||
mock.SignCheckDeliver(t, mapp.BaseApp, []sdk.Msg{createValidatorMsg}, []uint64{0}, []uint64{0}, true, true, priv1)
|
||||
mock.SignCheckDeliver(t, mapp.Cdc, mapp.BaseApp, []sdk.Msg{createValidatorMsg}, []uint64{0}, []uint64{0}, true, true, priv1)
|
||||
mock.CheckBalance(t, mapp, addr1, sdk.Coins{genCoin.Minus(bondCoin)})
|
||||
mapp.BeginBlock(abci.RequestBeginBlock{})
|
||||
|
||||
|
@ -121,7 +123,7 @@ func TestSlashingMsgs(t *testing.T) {
|
|||
checkValidatorSigningInfo(t, mapp, keeper, sdk.ConsAddress(addr1), false)
|
||||
|
||||
// unjail should fail with unknown validator
|
||||
res := mock.SignCheckDeliver(t, mapp.BaseApp, []sdk.Msg{unjailMsg}, []uint64{0}, []uint64{1}, false, false, priv1)
|
||||
res := mock.SignCheckDeliver(t, mapp.Cdc, mapp.BaseApp, []sdk.Msg{unjailMsg}, []uint64{0}, []uint64{1}, false, false, priv1)
|
||||
require.EqualValues(t, CodeValidatorNotJailed, res.Code)
|
||||
require.EqualValues(t, DefaultCodespace, res.Codespace)
|
||||
}
|
||||
|
|
|
@ -120,7 +120,7 @@ func TestStakingMsgs(t *testing.T) {
|
|||
sdk.ValAddress(addr1), priv1.PubKey(), bondCoin, description, commissionMsg,
|
||||
)
|
||||
|
||||
mock.SignCheckDeliver(t, mApp.BaseApp, []sdk.Msg{createValidatorMsg}, []uint64{0}, []uint64{0}, true, true, priv1)
|
||||
mock.SignCheckDeliver(t, mApp.Cdc, mApp.BaseApp, []sdk.Msg{createValidatorMsg}, []uint64{0}, []uint64{0}, true, true, priv1)
|
||||
mock.CheckBalance(t, mApp, addr1, sdk.Coins{genCoin.Minus(bondCoin)})
|
||||
mApp.BeginBlock(abci.RequestBeginBlock{})
|
||||
|
||||
|
@ -134,7 +134,7 @@ func TestStakingMsgs(t *testing.T) {
|
|||
addr1, sdk.ValAddress(addr2), priv2.PubKey(), bondCoin, description, commissionMsg,
|
||||
)
|
||||
|
||||
mock.SignCheckDeliver(t, mApp.BaseApp, []sdk.Msg{createValidatorMsgOnBehalfOf}, []uint64{0, 0}, []uint64{1, 0}, true, true, priv1, priv2)
|
||||
mock.SignCheckDeliver(t, mApp.Cdc, mApp.BaseApp, []sdk.Msg{createValidatorMsgOnBehalfOf}, []uint64{0, 0}, []uint64{1, 0}, true, true, priv1, priv2)
|
||||
mock.CheckBalance(t, mApp, addr1, sdk.Coins{genCoin.Minus(bondCoin).Minus(bondCoin)})
|
||||
mApp.BeginBlock(abci.RequestBeginBlock{})
|
||||
|
||||
|
@ -150,7 +150,7 @@ func TestStakingMsgs(t *testing.T) {
|
|||
description = NewDescription("bar_moniker", "", "", "")
|
||||
editValidatorMsg := NewMsgEditValidator(sdk.ValAddress(addr1), description, nil)
|
||||
|
||||
mock.SignCheckDeliver(t, mApp.BaseApp, []sdk.Msg{editValidatorMsg}, []uint64{0}, []uint64{2}, true, true, priv1)
|
||||
mock.SignCheckDeliver(t, mApp.Cdc, mApp.BaseApp, []sdk.Msg{editValidatorMsg}, []uint64{0}, []uint64{2}, true, true, priv1)
|
||||
validator = checkValidator(t, mApp, keeper, sdk.ValAddress(addr1), true)
|
||||
require.Equal(t, description, validator.Description)
|
||||
|
||||
|
@ -158,13 +158,13 @@ func TestStakingMsgs(t *testing.T) {
|
|||
mock.CheckBalance(t, mApp, addr2, sdk.Coins{genCoin})
|
||||
delegateMsg := NewMsgDelegate(addr2, sdk.ValAddress(addr1), bondCoin)
|
||||
|
||||
mock.SignCheckDeliver(t, mApp.BaseApp, []sdk.Msg{delegateMsg}, []uint64{0}, []uint64{1}, true, true, priv2)
|
||||
mock.SignCheckDeliver(t, mApp.Cdc, mApp.BaseApp, []sdk.Msg{delegateMsg}, []uint64{0}, []uint64{1}, true, true, priv2)
|
||||
mock.CheckBalance(t, mApp, addr2, sdk.Coins{genCoin.Minus(bondCoin)})
|
||||
checkDelegation(t, mApp, keeper, addr2, sdk.ValAddress(addr1), true, sdk.NewDec(10))
|
||||
|
||||
// begin unbonding
|
||||
beginUnbondingMsg := NewMsgUndelegate(addr2, sdk.ValAddress(addr1), sdk.NewDec(10))
|
||||
mock.SignCheckDeliver(t, mApp.BaseApp, []sdk.Msg{beginUnbondingMsg}, []uint64{0}, []uint64{2}, true, true, priv2)
|
||||
mock.SignCheckDeliver(t, mApp.Cdc, mApp.BaseApp, []sdk.Msg{beginUnbondingMsg}, []uint64{0}, []uint64{2}, true, true, priv2)
|
||||
|
||||
// delegation should exist anymore
|
||||
checkDelegation(t, mApp, keeper, addr2, sdk.ValAddress(addr1), false, sdk.Dec{})
|
||||
|
|
Loading…
Reference in New Issue