forked from TrueCloudLab/neoneo-go
core: add benchmark for (*NEO).getGASPerVote
This commit is contained in:
parent
8c6de35ec2
commit
9879514412
2 changed files with 141 additions and 1 deletions
|
@ -10,6 +10,7 @@ import (
|
|||
"math/big"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
@ -68,6 +69,27 @@ func newTestChainWithCustomCfgAndStore(t testing.TB, st storage.Store, f func(*c
|
|||
return chain
|
||||
}
|
||||
|
||||
func newLevelDBForTesting(t testing.TB) storage.Store {
|
||||
ldbDir := t.TempDir()
|
||||
dbConfig := storage.DBConfiguration{
|
||||
Type: "leveldb",
|
||||
LevelDBOptions: storage.LevelDBOptions{
|
||||
DataDirectoryPath: ldbDir,
|
||||
},
|
||||
}
|
||||
newLevelStore, err := storage.NewLevelDBStore(dbConfig.LevelDBOptions)
|
||||
require.Nil(t, err, "NewLevelDBStore error")
|
||||
return newLevelStore
|
||||
}
|
||||
|
||||
func newBoltStoreForTesting(t testing.TB) storage.Store {
|
||||
d := t.TempDir()
|
||||
testFileName := filepath.Join(d, "test_bolt_db")
|
||||
boltDBStore, err := storage.NewBoltDBStore(storage.BoltDBOptions{FilePath: testFileName})
|
||||
require.NoError(t, err)
|
||||
return boltDBStore
|
||||
}
|
||||
|
||||
func initTestChain(t testing.TB, st storage.Store, f func(*config.Config)) *Blockchain {
|
||||
unitTestNetCfg, err := config.Load("../../config", testchain.Network())
|
||||
require.NoError(t, err)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"math/big"
|
||||
"sort"
|
||||
|
@ -10,6 +11,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/internal/testchain"
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/native"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
|
@ -31,7 +33,7 @@ func setSigner(tx *transaction.Transaction, h util.Uint160) {
|
|||
}}
|
||||
}
|
||||
|
||||
func checkTxHalt(t *testing.T, bc *Blockchain, h util.Uint256) {
|
||||
func checkTxHalt(t testing.TB, bc *Blockchain, h util.Uint256) {
|
||||
aer, err := bc.GetAppExecResults(h, trigger.Application)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(aer))
|
||||
|
@ -476,3 +478,119 @@ func newAccountWithGAS(t *testing.T, bc *Blockchain) *wallet.Account {
|
|||
transferTokenFromMultisigAccount(t, bc, acc.PrivateKey().GetScriptHash(), bc.contracts.GAS.Hash, 1000_00000000)
|
||||
return acc
|
||||
}
|
||||
|
||||
func BenchmarkNEO_GetGASPerVote(t *testing.B) {
|
||||
var stores = map[string]func(testing.TB) storage.Store{
|
||||
"MemPS": func(t testing.TB) storage.Store {
|
||||
return storage.NewMemoryStore()
|
||||
},
|
||||
"BoltPS": newBoltStoreForTesting,
|
||||
"LevelPS": newLevelDBForTesting,
|
||||
}
|
||||
for psName, newPS := range stores {
|
||||
for nRewardRecords := 10; nRewardRecords <= 1000; nRewardRecords *= 10 {
|
||||
for rewardDistance := 1; rewardDistance <= 1000; rewardDistance *= 10 {
|
||||
t.Run(fmt.Sprintf("%s_%dRewardRecords_%dRewardDistance", psName, nRewardRecords, rewardDistance), func(t *testing.B) {
|
||||
ps := newPS(t)
|
||||
t.Cleanup(func() { ps.Close() })
|
||||
benchmarkGasPerVote(t, ps, nRewardRecords, rewardDistance)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func benchmarkGasPerVote(t *testing.B, ps storage.Store, nRewardRecords int, rewardDistance int) {
|
||||
bc := newTestChainWithCustomCfgAndStore(t, ps, nil)
|
||||
|
||||
neo := bc.contracts.NEO
|
||||
tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0)
|
||||
ic := bc.newInteropContext(trigger.Application, bc.dao, nil, tx)
|
||||
ic.SpawnVM()
|
||||
ic.Block = bc.newBlock(tx)
|
||||
|
||||
advanceChain := func(t *testing.B, count int) {
|
||||
for i := 0; i < count; i++ {
|
||||
require.NoError(t, bc.AddBlock(bc.newBlock()))
|
||||
ic.Block.Index++
|
||||
}
|
||||
}
|
||||
|
||||
// Vote for new committee.
|
||||
sz := testchain.CommitteeSize()
|
||||
accs := make([]*wallet.Account, sz)
|
||||
candidates := make(keys.PublicKeys, sz)
|
||||
txs := make([]*transaction.Transaction, 0, len(accs))
|
||||
for i := 0; i < sz; i++ {
|
||||
priv, err := keys.NewPrivateKey()
|
||||
require.NoError(t, err)
|
||||
candidates[i] = priv.PublicKey()
|
||||
accs[i], err = wallet.NewAccount()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, neo.RegisterCandidateInternal(ic, candidates[i]))
|
||||
|
||||
to := accs[i].Contract.ScriptHash()
|
||||
w := io.NewBufBinWriter()
|
||||
emit.AppCall(w.BinWriter, bc.contracts.NEO.Hash, "transfer", callflag.All,
|
||||
neoOwner.BytesBE(), to.BytesBE(),
|
||||
big.NewInt(int64(sz-i)*1000000).Int64(), nil)
|
||||
emit.Opcodes(w.BinWriter, opcode.ASSERT)
|
||||
emit.AppCall(w.BinWriter, bc.contracts.GAS.Hash, "transfer", callflag.All,
|
||||
neoOwner.BytesBE(), to.BytesBE(),
|
||||
int64(1_000_000_000), nil)
|
||||
emit.Opcodes(w.BinWriter, opcode.ASSERT)
|
||||
require.NoError(t, w.Err)
|
||||
tx := transaction.New(w.Bytes(), 1000_000_000)
|
||||
tx.ValidUntilBlock = bc.BlockHeight() + 1
|
||||
setSigner(tx, testchain.MultisigScriptHash())
|
||||
require.NoError(t, testchain.SignTx(bc, tx))
|
||||
txs = append(txs, tx)
|
||||
}
|
||||
require.NoError(t, bc.AddBlock(bc.newBlock(txs...)))
|
||||
for _, tx := range txs {
|
||||
checkTxHalt(t, bc, tx.Hash())
|
||||
}
|
||||
for i := 0; i < sz; i++ {
|
||||
priv := accs[i].PrivateKey()
|
||||
h := priv.GetScriptHash()
|
||||
setSigner(tx, h)
|
||||
ic.VM.Load(priv.PublicKey().GetVerificationScript())
|
||||
require.NoError(t, neo.VoteInternal(ic, h, candidates[i]))
|
||||
}
|
||||
_, err := ic.DAO.Persist()
|
||||
require.NoError(t, err)
|
||||
|
||||
// Collect set of nRewardRecords reward records for each voter.
|
||||
advanceChain(t, nRewardRecords*testchain.CommitteeSize())
|
||||
|
||||
// Transfer some more NEO to first voter to update his balance height.
|
||||
to := accs[0].Contract.ScriptHash()
|
||||
w := io.NewBufBinWriter()
|
||||
emit.AppCall(w.BinWriter, bc.contracts.NEO.Hash, "transfer", callflag.All,
|
||||
neoOwner.BytesBE(), to.BytesBE(), int64(1), nil)
|
||||
emit.Opcodes(w.BinWriter, opcode.ASSERT)
|
||||
require.NoError(t, w.Err)
|
||||
tx = transaction.New(w.Bytes(), 1000_000_000)
|
||||
tx.ValidUntilBlock = bc.BlockHeight() + 1
|
||||
setSigner(tx, testchain.MultisigScriptHash())
|
||||
require.NoError(t, testchain.SignTx(bc, tx))
|
||||
require.NoError(t, bc.AddBlock(bc.newBlock(tx)))
|
||||
|
||||
aer, err := bc.GetAppExecResults(tx.Hash(), trigger.Application)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(aer))
|
||||
require.Equal(t, vm.HaltState, aer[0].VMState, aer[0].FaultException)
|
||||
|
||||
// Advance chain one more time to avoid same start/end rewarding bounds.
|
||||
advanceChain(t, rewardDistance)
|
||||
end := bc.BlockHeight()
|
||||
|
||||
t.ResetTimer()
|
||||
t.ReportAllocs()
|
||||
t.StartTimer()
|
||||
for i := 0; i < t.N; i++ {
|
||||
_, err := neo.CalculateBonus(ic.DAO, to, end)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
t.StopTimer()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue