Skip to content

Commit

Permalink
finalize
Browse files Browse the repository at this point in the history
  • Loading branch information
ysv committed Nov 10, 2023
1 parent 4f977b1 commit 4432869
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 23 deletions.
25 changes: 20 additions & 5 deletions x/deterministicgas/ante/ante.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
package ante

import (
"fmt"

sdk "github.com/cosmos/cosmos-sdk/types"
authante "github.com/cosmos/cosmos-sdk/x/auth/ante"

"github.com/CoreumFoundation/coreum/v3/x/deterministicgas"
)

type debugGasMeter struct {
sdk.GasMeter
}

func newDBG(g sdk.GasMeter) debugGasMeter {
return debugGasMeter{g}
}

func (dbg debugGasMeter) ConsumeGas(amount sdk.Gas, descriptor string) {
fmt.Printf("dbg gas: %v descriptor: %v\n", amount, descriptor)
dbg.GasMeter.ConsumeGas(amount, descriptor)
}

// SetInfiniteGasMeterDecorator sets the infinite gas limit for ante handler
// CONTRACT: Must be the first decorator in the chain.
// CONTRACT: Tx must implement GasTx interface.
Expand All @@ -28,7 +43,7 @@ func (sigmd SetInfiniteGasMeterDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx,
ctx.GasMeter().ConsumeGas(sigmd.deterministicGasConfig.FixedGas, "Fixed")

// Set infinite gas meter for ante handler
return next(ctx.WithGasMeter(sdk.NewInfiniteGasMeter()), tx, simulate)
return next(ctx.WithGasMeter(newDBG(sdk.NewInfiniteGasMeter())), tx, simulate)
}

// AddBaseGasDecorator adds free gas to gas meter.
Expand All @@ -52,14 +67,14 @@ func (abgd AddBaseGasDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate
if simulate || ctx.BlockHeight() == 0 {
// During simulation and genesis initialization infinite gas meter is set inside context by `SetUpContextDecorator`.
// Here, we reset it to initial state with 0 gas consumed.
gasMeter = sdk.NewInfiniteGasMeter()
gasMeter = newDBG(sdk.NewInfiniteGasMeter())
} else {
params := abgd.ak.GetParams(ctx)

// It is not needed to verify that tx really implements `GasTx` interface because it has been already done by
// `SetUpContextDecorator`
gasTx := tx.(authante.GasTx)
gasMeter = sdk.NewGasMeter(gasTx.GetGas() + abgd.deterministicGasConfig.TxBaseGas(params))
gasMeter = newDBG(sdk.NewGasMeter(gasTx.GetGas() + abgd.deterministicGasConfig.TxBaseGas(params)))
}
return next(ctx.WithGasMeter(gasMeter), tx, simulate)
}
Expand Down Expand Up @@ -91,9 +106,9 @@ func (cfgd ChargeFixedGasDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simul
if simulate || ctx.BlockHeight() == 0 {
// During simulation and genesis initialization infinite gas meter is set inside context by `SetUpContextDecorator`.
// We reset it to initial state with 0 gas consumed.
gasMeter = sdk.NewInfiniteGasMeter()
gasMeter = newDBG(sdk.NewInfiniteGasMeter())
} else {
gasMeter = sdk.NewGasMeter(gasTx.GetGas())
gasMeter = newDBG(sdk.NewGasMeter(gasTx.GetGas()))
}

gasConsumed := ctx.GasMeter().GasConsumed()
Expand Down
21 changes: 13 additions & 8 deletions x/deterministicgas/spec/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,36 @@ complicated, nondeterministic execution path (e.g `/cosmwasm.wasm.v1.MsgExecuteC
Here is formula for the transaction

`
Gas = FixedGas + Sum(Gas for each message) + GasForExtraBytes + GasForExtraSignatures
Gas = FixedGas + max((GasForBytes + GasForSignatures - TxBaseGas), 0) + Sum(Gas for each message)
`

If message type is deterministic, then the value is looked up from the table, if it is non-deterministic, then the
required gas is determined after the execution.

`
GasForExtraBytes = max(0, TxByteSize-FreeBytes) * TxSizeCostPerByte
GasForBytes = TxByteSize * TxSizeCostPerByte
`

`
GasForExtraSignatures = max(0, NumOfSigs-FreeSigs) * SigVerifyCost
GasForSignatures = NumOfSigs * SigVerifyCost
`

Currently, we have values for the above variables as follows:

- `FixedGas`: 65000
- `TxBaseGas`: 21480
- `SigVerifyCost`: 1000
- `TxSizeCostPerByte`: 10
- `FreeSignatures`: 1
- `FreeBytes`: 2048

As an example if the transaction has 1 signature on it and is below
2048 bytes, the user will not pay anything extra, and if one of those values exceed those limits, the user will pay for
the extra resources.

To summarize user pays FixedGas as long as `GasForBytes + GasForSignatures <= TxBaseGas`.
If `GasForBytes + GasForSignatures > TxBaseGas` user will have to pay anything above `TxBaseGas` on top of `FixedGas`.

As an example if the transaction has 1 signature on it and size is below
2048 bytes, the user will not pay anything extra. Or user can have multiple signatures but fewer bytes then nothing extra should be paid.


### Full examples

Expand All @@ -50,7 +55,7 @@ Let's say we have a transaction with 1 messages of type
signatures and the tx size is 1000 bytes, total will be:

`
TotalGas = 65000 + 1 * 50000 + (1 - 1) * 1000 + max(0, 1000-2048) * 10
TotalGas = 65000 + max(0, (21480 - 1 * 1000 + 1000 * 10)) + 1 * 50000
`

#### Example 2
Expand All @@ -59,7 +64,7 @@ Let's say we have a transaction with 2 messages of type
signatures and the tx size is 2050 bytes, total will be:

`
TotalGas = 65000 + 2 * 70000 + (2 - 1) * 1000 + max(0, 2050-2048) * 10
TotalGas = 65000 + max(0, (21480 - 2 * 1000 + 2050 * 10)) + 2 * 70000
`

## Gas Tables
Expand Down
21 changes: 13 additions & 8 deletions x/deterministicgas/spec/README.tmpl.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,31 +15,36 @@ complicated, nondeterministic execution path (e.g `/cosmwasm.wasm.v1.MsgExecuteC
Here is formula for the transaction

`
Gas = FixedGas + Sum(Gas for each message) + GasForExtraBytes + GasForExtraSignatures
Gas = FixedGas + max((GasForBytes + GasForSignatures - TxBaseGas), 0) + Sum(Gas for each message)
`

If message type is deterministic, then the value is looked up from the table, if it is non-deterministic, then the
required gas is determined after the execution.

`
GasForExtraBytes = max(0, TxByteSize-FreeBytes) * TxSizeCostPerByte
GasForBytes = TxByteSize * TxSizeCostPerByte
`

`
GasForExtraSignatures = max(0, NumOfSigs-FreeSigs) * SigVerifyCost
GasForSignatures = NumOfSigs * SigVerifyCost
`

Currently, we have values for the above variables as follows:

- `FixedGas`: {{ .FixedGas }}
- `TxBaseGas`: {{ .TxBaseGas }}
- `SigVerifyCost`: {{ .SigVerifyCost }}
- `TxSizeCostPerByte`: {{ .TxSizeCostPerByte }}
- `FreeSignatures`: {{ .FreeSignatures }}
- `FreeBytes`: {{ .FreeBytes }}

As an example if the transaction has 1 signature on it and is below
2048 bytes, the user will not pay anything extra, and if one of those values exceed those limits, the user will pay for
the extra resources.

To summarize user pays FixedGas as long as `GasForBytes + GasForSignatures <= TxBaseGas`.
If `GasForBytes + GasForSignatures > TxBaseGas` user will have to pay anything above `TxBaseGas` on top of `FixedGas`.

As an example if the transaction has 1 signature on it and size is below
2048 bytes, the user will not pay anything extra. Or user can have multiple signatures but fewer bytes then nothing extra should be paid.


### Full examples

Expand All @@ -49,7 +54,7 @@ Let's say we have a transaction with 1 messages of type
signatures and the tx size is 1000 bytes, total will be:

`
TotalGas = {{ .FixedGas }} + 1 * {{ .BankSendPerCoinGas }} + (1 - 1) * {{ .SigVerifyCost }} + max(0, 1000-{{ .FreeBytes }}) * {{ .TxSizeCostPerByte }}
TotalGas = {{ .FixedGas }} + max(0, ({{ .TxBaseGas }} - 1 * {{ .SigVerifyCost }} + 1000 * {{ .TxSizeCostPerByte }})) + 1 * {{ .BankSendPerCoinGas }}
`

#### Example 2
Expand All @@ -58,7 +63,7 @@ Let's say we have a transaction with 2 messages of type
signatures and the tx size is 2050 bytes, total will be:

`
TotalGas = {{ .FixedGas }} + 2 * {{ .MsgIssueGasPrice }} + (2 - 1) * {{ .SigVerifyCost }} + max(0, 2050-{{ .FreeBytes }}) * {{ .TxSizeCostPerByte }}
TotalGas = {{ .FixedGas }} + max(0, ({{ .TxBaseGas }} - 2 * {{ .SigVerifyCost }} + 2050 * {{ .TxSizeCostPerByte }})) + 2 * {{ .MsgIssueGasPrice }}
`

## Gas Tables
Expand Down
7 changes: 5 additions & 2 deletions x/deterministicgas/spec/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,13 @@ func main() {
panic(err)
}

authParams := auth.DefaultParams()
err = template.Must(template.New("README.md").Parse(readmeTmpl)).Execute(file, struct {
GeneratorComment string
SigVerifyCost uint64
TxSizeCostPerByte uint64
FixedGas uint64
TxBaseGas uint64
FreeBytes uint64
FreeSignatures uint64

Expand All @@ -95,8 +97,9 @@ func main() {
}{
GeneratorComment: generatorComment,
FixedGas: cfg.FixedGas,
SigVerifyCost: auth.DefaultSigVerifyCostSecp256k1,
TxSizeCostPerByte: auth.DefaultTxSizeCostPerByte,
TxBaseGas: cfg.TxBaseGas(authParams),
SigVerifyCost: authParams.SigVerifyCostSecp256k1,
TxSizeCostPerByte: authParams.TxSizeCostPerByte,
FreeBytes: cfg.FreeBytes,
FreeSignatures: cfg.FreeSignatures,

Expand Down

0 comments on commit 4432869

Please sign in to comment.