2021-08-05 06:59:48 +00:00
|
|
|
package core
|
|
|
|
|
|
|
|
import (
|
2022-01-18 16:44:01 +00:00
|
|
|
"fmt"
|
2021-08-05 06:59:48 +00:00
|
|
|
"testing"
|
|
|
|
|
2022-01-18 16:44:01 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/internal/random"
|
|
|
|
"github.com/nspcc-dev/neo-go/internal/testchain"
|
2021-08-05 06:59:48 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
2022-01-18 16:44:01 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
|
|
|
"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/io"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
2021-08-05 06:59:48 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
func BenchmarkVerifyWitness(t *testing.B) {
|
|
|
|
bc := newTestChain(t)
|
|
|
|
acc, err := wallet.NewAccount()
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
tx := bc.newTestTx(acc.Contract.ScriptHash(), []byte{byte(opcode.PUSH1)})
|
|
|
|
require.NoError(t, acc.SignTx(netmode.UnitTestNet, tx))
|
|
|
|
|
|
|
|
t.ResetTimer()
|
|
|
|
for n := 0; n < t.N; n++ {
|
2021-10-25 14:42:20 +00:00
|
|
|
_, _ = bc.VerifyWitness(tx.Signers[0].Account, tx, &tx.Scripts[0], 100000000)
|
2021-08-05 06:59:48 +00:00
|
|
|
}
|
|
|
|
}
|
2022-01-18 16:44:01 +00:00
|
|
|
|
|
|
|
func BenchmarkBlockchain_ForEachNEP17Transfer(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,
|
|
|
|
}
|
|
|
|
startFrom := []int{1, 100, 1000}
|
|
|
|
blocksToTake := []int{100, 1000}
|
|
|
|
for psName, newPS := range stores {
|
|
|
|
for _, startFromBlock := range startFrom {
|
|
|
|
for _, nBlocksToTake := range blocksToTake {
|
|
|
|
t.Run(fmt.Sprintf("%s_StartFromBlockN-%d_Take%dBlocks", psName, startFromBlock, nBlocksToTake), func(t *testing.B) {
|
|
|
|
ps := newPS(t)
|
|
|
|
t.Cleanup(func() { ps.Close() })
|
|
|
|
benchmarkForEachNEP17Transfer(t, ps, startFromBlock, nBlocksToTake)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func benchmarkForEachNEP17Transfer(t *testing.B, ps storage.Store, startFromBlock, nBlocksToTake int) {
|
|
|
|
var (
|
|
|
|
nonce uint32 = 1
|
|
|
|
chainHeight = 2_100 // constant chain height to be able to compare paging results
|
|
|
|
transfersPerBlock = state.TokenTransferBatchSize/4 + // 4 blocks per batch
|
|
|
|
state.TokenTransferBatchSize/32 // shift
|
|
|
|
)
|
|
|
|
|
|
|
|
bc := newTestChainWithCustomCfgAndStore(t, ps, nil)
|
|
|
|
gasHash := bc.contracts.GAS.Hash
|
|
|
|
acc := random.Uint160()
|
|
|
|
|
|
|
|
for j := 0; j < chainHeight; j++ {
|
|
|
|
w := io.NewBufBinWriter()
|
|
|
|
for i := 0; i < transfersPerBlock; i++ {
|
|
|
|
emit.AppCall(w.BinWriter, gasHash, "transfer", callflag.All, testchain.MultisigScriptHash(), acc, 1, nil)
|
|
|
|
emit.Opcodes(w.BinWriter, opcode.ASSERT)
|
|
|
|
require.NoError(t, w.Err)
|
|
|
|
}
|
|
|
|
script := w.Bytes()
|
|
|
|
tx := transaction.New(script, int64(1100_0000*transfersPerBlock))
|
|
|
|
tx.ValidUntilBlock = bc.BlockHeight() + 1
|
|
|
|
tx.Nonce = nonce
|
|
|
|
nonce++
|
|
|
|
tx.Signers = []transaction.Signer{{
|
|
|
|
Account: testchain.MultisigScriptHash(),
|
|
|
|
Scopes: transaction.CalledByEntry,
|
|
|
|
AllowedContracts: nil,
|
|
|
|
AllowedGroups: nil,
|
|
|
|
}}
|
|
|
|
require.NoError(t, testchain.SignTx(bc, tx))
|
|
|
|
b := bc.newBlock(tx)
|
|
|
|
require.NoError(t, bc.AddBlock(b))
|
|
|
|
checkTxHalt(t, bc, tx.Hash())
|
|
|
|
}
|
|
|
|
|
|
|
|
newestB, err := bc.GetBlock(bc.GetHeaderHash(int(bc.BlockHeight()) - startFromBlock + 1))
|
|
|
|
require.NoError(t, err)
|
2022-01-18 15:28:24 +00:00
|
|
|
newestTimestamp := newestB.Timestamp
|
2022-01-18 16:44:01 +00:00
|
|
|
oldestB, err := bc.GetBlock(bc.GetHeaderHash(int(newestB.Index) - nBlocksToTake))
|
|
|
|
require.NoError(t, err)
|
|
|
|
oldestTimestamp := oldestB.Timestamp
|
|
|
|
|
|
|
|
t.ResetTimer()
|
|
|
|
t.ReportAllocs()
|
|
|
|
t.StartTimer()
|
|
|
|
for i := 0; i < t.N; i++ {
|
2022-01-18 15:28:24 +00:00
|
|
|
require.NoError(t, bc.ForEachNEP17Transfer(acc, newestTimestamp, func(t *state.NEP17Transfer) (bool, error) {
|
2022-01-18 16:44:01 +00:00
|
|
|
if t.Timestamp < oldestTimestamp {
|
|
|
|
// iterating from newest to oldest, already have reached the needed height
|
|
|
|
return false, nil
|
|
|
|
}
|
|
|
|
return true, nil
|
|
|
|
}))
|
|
|
|
}
|
|
|
|
t.StopTimer()
|
|
|
|
}
|