Benchmarks for gas pricing (#634)
* Run benchmarks on circle CI * Add benchmark for secp256k1 verification * Add compilation benchmark * Move parallelism back to 1 for benchmarks * Review comments Co-authored-by: Alex Peters <alpe@users.noreply.github.com>
This commit is contained in:
@@ -86,6 +86,20 @@ jobs:
|
||||
- store_artifacts:
|
||||
path: /tmp/logs
|
||||
|
||||
benchmark:
|
||||
executor: golang
|
||||
parallelism: 1
|
||||
steps:
|
||||
- checkout
|
||||
- restore_cache:
|
||||
keys:
|
||||
- go-mod-v1-{{ checksum "go.sum" }}
|
||||
- run:
|
||||
name: Run benchmarks
|
||||
command: |
|
||||
cd ./x/wasm/keeper
|
||||
go test -bench .
|
||||
|
||||
upload-coverage:
|
||||
executor: golang
|
||||
steps:
|
||||
@@ -178,3 +192,6 @@ workflows:
|
||||
- upload-coverage:
|
||||
requires:
|
||||
- test-cover
|
||||
- benchmark:
|
||||
requires:
|
||||
- test-cover
|
||||
|
||||
@@ -1,15 +1,41 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"github.com/CosmWasm/wasmd/x/wasm/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/syndtr/goleveldb/leveldb/opt"
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
|
||||
"github.com/stretchr/testify/require"
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
|
||||
"github.com/CosmWasm/wasmd/x/wasm/types"
|
||||
)
|
||||
|
||||
func BenchmarkExecution(b *testing.B) {
|
||||
// BenchmarkVerification benchmarks secp256k1 verification which is 1000 gas based on cpu time.
|
||||
//
|
||||
// Just this function is copied from
|
||||
// https://github.com/cosmos/cosmos-sdk/blob/90e9370bd80d9a3d41f7203ddb71166865561569/crypto/keys/internal/benchmarking/bench.go#L48-L62
|
||||
// And thus under the GO license (BSD style)
|
||||
func BenchmarkGasNormalization(b *testing.B) {
|
||||
priv := secp256k1.GenPrivKey()
|
||||
pub := priv.PubKey()
|
||||
|
||||
// use a short message, so this time doesn't get dominated by hashing.
|
||||
message := []byte("Hello, world!")
|
||||
signature, err := priv.Sign(message)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
pub.VerifySignature(message, signature)
|
||||
}
|
||||
}
|
||||
|
||||
// By comparing the timing for queries on pinned vs unpinned, the difference gives us the overhead of
|
||||
// instantiating an unpinned contract. That value can be used to determine a reasonable gas price
|
||||
// for the InstantiationCost
|
||||
func BenchmarkInstantiationOverhead(b *testing.B) {
|
||||
specs := map[string]struct {
|
||||
pinned bool
|
||||
db func() dbm.DB
|
||||
@@ -21,21 +47,6 @@ func BenchmarkExecution(b *testing.B) {
|
||||
db: func() dbm.DB { return dbm.NewMemDB() },
|
||||
pinned: true,
|
||||
},
|
||||
"unpinned, level db": {
|
||||
db: func() dbm.DB {
|
||||
levelDB, err := dbm.NewGoLevelDBWithOpts("testing", b.TempDir(), &opt.Options{BlockCacher: opt.NoCacher})
|
||||
require.NoError(b, err)
|
||||
return levelDB
|
||||
},
|
||||
},
|
||||
"pinned, level db": {
|
||||
db: func() dbm.DB {
|
||||
levelDB, err := dbm.NewGoLevelDBWithOpts("testing", b.TempDir(), &opt.Options{BlockCacher: opt.NoCacher})
|
||||
require.NoError(b, err)
|
||||
return levelDB
|
||||
},
|
||||
pinned: true,
|
||||
},
|
||||
}
|
||||
for name, spec := range specs {
|
||||
b.Run(name, func(b *testing.B) {
|
||||
@@ -53,3 +64,39 @@ func BenchmarkExecution(b *testing.B) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate the time it takes to compile some wasm code the first time.
|
||||
// This will help us adjust pricing for UploadCode
|
||||
func BenchmarkCompilation(b *testing.B) {
|
||||
specs := map[string]struct {
|
||||
wasmFile string
|
||||
}{
|
||||
"hackatom": {
|
||||
wasmFile: "./testdata/hackatom.wasm",
|
||||
},
|
||||
"burner": {
|
||||
wasmFile: "./testdata/burner.wasm",
|
||||
},
|
||||
"ibc_reflect": {
|
||||
wasmFile: "./testdata/ibc_reflect.wasm",
|
||||
},
|
||||
}
|
||||
|
||||
for name, spec := range specs {
|
||||
b.Run(name, func(b *testing.B) {
|
||||
wasmConfig := types.WasmConfig{MemoryCacheSize: 0}
|
||||
db := dbm.NewMemDB()
|
||||
ctx, keepers := createTestInput(b, false, SupportedFeatures, wasmConfig, db)
|
||||
|
||||
// print out code size for comparisons
|
||||
code, err := ioutil.ReadFile(spec.wasmFile)
|
||||
require.NoError(b, err)
|
||||
b.Logf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b(size: %d) ", len(code))
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = StoreExampleContract(b, ctx, keepers, spec.wasmFile)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user