Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Benchmarks for gas pricing #634

Merged
merged 5 commits into from
Oct 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -178,3 +192,6 @@ workflows:
- upload-coverage:
requires:
- test-cover
- benchmark:
requires:
- test-cover
85 changes: 66 additions & 19 deletions x/wasm/keeper/bench_test.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,41 @@
package keeper

import (
"github.com/CosmWasm/wasmd/x/wasm/types"
"io/ioutil"
"testing"

"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
"github.com/stretchr/testify/require"
"github.com/syndtr/goleveldb/leveldb/opt"
dbm "github.com/tendermint/tm-db"
"testing"

"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
Expand All @@ -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) {
Expand All @@ -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)
}
})
}
}