Skip to content

Commit

Permalink
Refactor to sims2 msg factories
Browse files Browse the repository at this point in the history
  • Loading branch information
alpe committed Sep 6, 2024
1 parent e9d72f5 commit 4f4db31
Show file tree
Hide file tree
Showing 141 changed files with 6,212 additions and 9,637 deletions.
59 changes: 18 additions & 41 deletions scripts/build/simulations.mk
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#? test-sim-nondeterminism: Run non-determinism test for simapp
test-sim-nondeterminism:
@echo "Running non-determinism test..."
@cd ${CURRENT_DIR}/simapp && go test -mod=readonly -timeout=30m -tags='sims' -run TestAppStateDeterminism \
@cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -timeout=30m -tags='sims' -run TestAppStateDeterminism \
-NumBlocks=100 -BlockSize=200 -Period=0

# Requires an exported plugin. See store/streaming/README.md for documentation.
Expand All @@ -16,45 +16,49 @@ test-sim-nondeterminism:
# make test-sim-nondeterminism-streaming
test-sim-nondeterminism-streaming:
@echo "Running non-determinism-streaming test..."
@cd ${CURRENT_DIR}/simapp && go test -mod=readonly -timeout=30m -tags='sims' -run TestAppStateDeterminism \
@cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -timeout=30m -tags='sims' -run TestAppStateDeterminism \
-NumBlocks=100 -BlockSize=200 -Period=0 -EnableStreaming=true

test-sim-custom-genesis-fast:
@echo "Running custom genesis simulation..."
@echo "By default, ${HOME}/.simapp/config/genesis.json will be used."
@cd ${CURRENT_DIR}/simapp && go test -mod=readonly -timeout=30m -tags='sims' -run TestFullAppSimulation -Genesis=${HOME}/.simapp/config/genesis.json \
@cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -timeout=30m -tags='sims' -run TestFullAppSimulation -Genesis=${HOME}/.simapp/config/genesis.json \
-NumBlocks=100 -BlockSize=200 -Seed=99 -Period=5 -SigverifyTx=false

test-sim-import-export:
@echo "Running application import/export simulation. This may take several minutes..."
@cd ${CURRENT_DIR}/simapp && go test -mod=readonly -timeout 20m -tags='sims' -run TestAppImportExport \
@cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -timeout 20m -tags='sims' -run TestAppImportExport \
-NumBlocks=50 -Period=5

test-sim-after-import:
@echo "Running application simulation-after-import. This may take several minutes..."
@cd ${CURRENT_DIR}/simapp && go test -mod=readonly -timeout 30m -tags='sims' -run TestAppSimulationAfterImport \
@cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -timeout 30m -tags='sims' -run TestAppSimulationAfterImport \
-NumBlocks=50 -Period=5


test-sim-custom-genesis-multi-seed:
@echo "Running multi-seed custom genesis simulation..."
@echo "By default, ${HOME}/.simapp/config/genesis.json will be used."
@cd ${CURRENT_DIR}/simapp && go test -mod=readonly -timeout 30m -tags='sims' -run TestFullAppSimulation -Genesis=${HOME}/.simapp/config/genesis.json \
@cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -timeout 30m -tags='sims' -run TestFullAppSimulation -Genesis=${HOME}/.simapp/config/genesis.json \
-NumBlocks=400 -Period=5

test-sim-multi-seed-long:
@echo "Running long multi-seed application simulation. This may take awhile!"
@cd ${CURRENT_DIR}/simapp && go test -mod=readonly -timeout=2h -tags='sims' -run TestFullAppSimulation \
@cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -timeout=2h -tags='sims' -run TestFullAppSimulation \
-NumBlocks=150 -Period=50

test-sim-multi-seed-short:
@echo "Running short multi-seed application simulation. This may take awhile!"
@cd ${CURRENT_DIR}/simapp && go test -mod=readonly -timeout 30m -tags='sims' -run TestFullAppSimulation \
-NumBlocks=50 -Period=10
@cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -timeout 30m -tags='sims' -run TestFullAppSimulation \
-NumBlocks=50 -Period=10 -FauxMerkle=true

test-v2-sim-wip:
@echo "Running v2 simapp. This may take awhile!"
@cd ${CURRENT_DIR}/simapp/v2 && go test -failfast -mod=readonly -timeout 30m -tags='sims' -run TestSimsAppV2

test-sim-benchmark-invariants:
@echo "Running simulation invariant benchmarks..."
cd ${CURRENT_DIR}/simapp && go test -mod=readonly -benchmem -bench=BenchmarkInvariants -tags='sims' -run=^$ \
cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -benchmem -bench=BenchmarkInvariants -tags='sims' -run=^$ \
-Enabled=true -NumBlocks=1000 -BlockSize=200 \
-Period=1 -Commit=true -Seed=57 -v -timeout 24h

Expand All @@ -77,50 +81,23 @@ SIM_COMMIT ?= true
test-sim-fuzz:
@echo "Running application fuzz for numBlocks=2, blockSize=20. This may take awhile!"
#ld flags are a quick fix to make it work on current osx
@cd ${CURRENT_DIR}/simapp && go test -mod=readonly -json -tags='sims' -ldflags="-extldflags=-Wl,-ld_classic" -timeout=60m -fuzztime=60m -run=^$$ -fuzz=FuzzFullAppSimulation -GenesisTime=1714720615 -NumBlocks=2 -BlockSize=20
@cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -json -tags='sims' -ldflags="-extldflags=-Wl,-ld_classic" -timeout=60m -fuzztime=60m -run=^$$ -fuzz=FuzzFullAppSimulation -GenesisTime=1714720615 -NumBlocks=2 -BlockSize=20

#? test-sim-benchmark: Run benchmark test for simapp
test-sim-benchmark:
@echo "Running application benchmark for numBlocks=$(SIM_NUM_BLOCKS), blockSize=$(SIM_BLOCK_SIZE). This may take awhile!"
@cd ${CURRENT_DIR}/simapp && go test -mod=readonly -tags='sims' -run=^$$ $(.) -bench ^BenchmarkFullAppSimulation$$ \
@cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -tags='sims' -run=^$$ $(.) -bench ^BenchmarkFullAppSimulation$$ \
-Enabled=true -NumBlocks=$(SIM_NUM_BLOCKS) -BlockSize=$(SIM_BLOCK_SIZE) -Commit=$(SIM_COMMIT) -timeout 24h

# Requires an exported plugin. See store/streaming/README.md for documentation.
#
# example:
# export COSMOS_SDK_ABCI_V1=<path-to-plugin-binary>
# make test-sim-benchmark-streaming
#
# Using the built-in examples:
# export COSMOS_SDK_ABCI_V1=<path-to-sdk>/store/streaming/abci/examples/file/file
# make test-sim-benchmark-streaming
test-sim-benchmark-streaming:
@echo "Running application benchmark for numBlocks=$(SIM_NUM_BLOCKS), blockSize=$(SIM_BLOCK_SIZE). This may take awhile!"
@cd ${CURRENT_DIR}/simapp && go test -mod=readonly -tags='sims' -run=^$$ $(.) -bench ^BenchmarkFullAppSimulation$$ \
-Enabled=true -NumBlocks=$(SIM_NUM_BLOCKS) -BlockSize=$(SIM_BLOCK_SIZE) -Commit=$(SIM_COMMIT) -timeout 24h -EnableStreaming=true

test-sim-profile:
@echo "Running application benchmark for numBlocks=$(SIM_NUM_BLOCKS), blockSize=$(SIM_BLOCK_SIZE). This may take awhile!"
@cd ${CURRENT_DIR}/simapp && go test -mod=readonly -tags='sims' -benchmem -run=^$$ $(.) -bench ^BenchmarkFullAppSimulation$$ \
@cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -tags='sims' -benchmem -run=^$$ $(.) -bench ^BenchmarkFullAppSimulation$$ \
-Enabled=true -NumBlocks=$(SIM_NUM_BLOCKS) -BlockSize=$(SIM_BLOCK_SIZE) -Commit=$(SIM_COMMIT) -timeout 24h -cpuprofile cpu.out -memprofile mem.out

# Requires an exported plugin. See store/streaming/README.md for documentation.
#
# example:
# export COSMOS_SDK_ABCI_V1=<path-to-plugin-binary>
# make test-sim-profile-streaming
#
# Using the built-in examples:
# export COSMOS_SDK_ABCI_V1=<path-to-sdk>/store/streaming/abci/examples/file/file
# make test-sim-profile-streaming
test-sim-profile-streaming:
@echo "Running application benchmark for numBlocks=$(SIM_NUM_BLOCKS), blockSize=$(SIM_BLOCK_SIZE). This may take awhile!"
@cd ${CURRENT_DIR}/simapp && go test -mod=readonly -tags='sims' -benchmem -run=^$$ $(.) -bench ^BenchmarkFullAppSimulation$$ \
-Enabled=true -NumBlocks=$(SIM_NUM_BLOCKS) -BlockSize=$(SIM_BLOCK_SIZE) -Commit=$(SIM_COMMIT) -timeout 24h -cpuprofile cpu.out -memprofile mem.out -EnableStreaming=true

.PHONY: test-sim-profile test-sim-benchmark test-sim-fuzz

#? benchmark: Run benchmark tests
benchmark:
@go test -mod=readonly -bench=. $(PACKAGES_NOSIMULATION)
@go test -failfast -mod=readonly -bench=. $(PACKAGES_NOSIMULATION)
.PHONY: benchmark
21 changes: 21 additions & 0 deletions server/v2/appmanager/appmanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,27 @@ func (a AppManager[T]) DeliverBlock(

return blockResponse, newState, nil
}
func (a AppManager[T]) DeliverSims(
ctx context.Context,
block *server.BlockRequest[T],
simsBuilder func(ctx context.Context) (T, bool),
) (*server.BlockResponse, corestore.WriterMap, error) {
latestVersion, currentState, err := a.db.StateLatest()
if err != nil {
return nil, nil, fmt.Errorf("unable to create new state for height %d: %w", block.Height, err)
}

if latestVersion+1 != block.Height {
return nil, nil, fmt.Errorf("invalid DeliverBlock height wanted %d, got %d", latestVersion+1, block.Height)
}

blockResponse, newState, err := a.stf.DeliverSims(ctx, block, currentState, simsBuilder)
if err != nil {
return nil, nil, fmt.Errorf("block delivery failed: %w", err)
}

return blockResponse, newState, nil
}

// ValidateTx will validate the tx against the latest storage state. This means that
// only the stateful validation will be run, not the execution portion of the tx.
Expand Down
7 changes: 7 additions & 0 deletions server/v2/appmanager/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,11 @@ type StateTransitionFunction[T transaction.Tx] interface {
state store.ReaderMap,
closure func(ctx context.Context) error,
) (store.WriterMap, error)

DeliverSims(
ctx context.Context,
block *server.BlockRequest[T],
state store.ReaderMap,
simsBuilder func(ctx context.Context) (T, bool),
) (blockResult *server.BlockResponse, newState store.WriterMap, err error)
}
5 changes: 4 additions & 1 deletion server/v2/stf/branch/changeset.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ type memIterator struct {
// The `valid` field of the iterator indicates whether the iterator is positioned at a valid key.
// The `start` and `end` fields of the iterator store the start and end keys respectively.
func newMemIterator(start, end []byte, tree *btree.BTreeG[item], ascending bool) *memIterator {
iter := tree.Iter()
iter := tree.Copy().Iter()
var valid bool
if ascending {
if start != nil {
Expand Down Expand Up @@ -208,6 +208,9 @@ func (mi *memIterator) keyInRange(key []byte) bool {
if !mi.ascending && mi.start != nil && bytes.Compare(key, mi.start) < 0 {
return false
}
if !mi.ascending && mi.end != nil && bytes.Compare(key, mi.end) >= 0 {
return false
}
return true
}

Expand Down
125 changes: 125 additions & 0 deletions server/v2/stf/branch/changeset_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package branch

import (
"bytes"
corestore "cosmossdk.io/core/store"
"reflect"
"testing"
)

func TestChangeSet_Next(t *testing.T) {
tests := map[string]struct {
setup func() corestore.Iterator
expected []string // expected keys sequence
}{
"both iterators are empty": {
setup: func() corestore.Iterator {
parent := newChangeSet()
cache := newChangeSet()
return mergeIterators(must(parent.iterator(nil, nil)), must(cache.iterator(nil, nil)), true)
},
},
"parent iterator has one item, cache is empty": {
setup: func() corestore.Iterator {
parent := newChangeSet()
parent.set([]byte("k1"), []byte("1"))
cache := newChangeSet()
return mergeIterators(must(parent.iterator(nil, nil)), must(cache.iterator(nil, nil)), true)
},
expected: []string{"k1"},
},
"cache has one item, parent is empty": {
setup: func() corestore.Iterator {
parent := newChangeSet()
cache := newChangeSet()
cache.set([]byte("k1"), []byte("1"))
return mergeIterators(must(parent.iterator(nil, nil)), must(cache.iterator(nil, nil)), true)
},
expected: []string{"k1"},
},
"both iterators have items, but cache value is nil": {
setup: func() corestore.Iterator {
parent := newChangeSet()
parent.set([]byte("k1"), []byte("1"))
cache := newChangeSet()
cache.set([]byte("k1"), nil)
return mergeIterators(must(parent.iterator(nil, nil)), must(cache.iterator(nil, nil)), true)
},
},
"parent and cache are ascending": {
setup: func() corestore.Iterator {
parent := newChangeSet()
parent.set([]byte("k2"), []byte("v2"))
parent.set([]byte("k3"), []byte("v3"))
cache := newChangeSet()
cache.set([]byte("k1"), []byte("v1"))
cache.set([]byte("k4"), []byte("v4"))
return mergeIterators(must(parent.iterator(nil, nil)), must(cache.iterator(nil, nil)), true)
},
expected: []string{"k1", "k2", "k3", "k4"},
},
"parent and cache are descending": {
setup: func() corestore.Iterator {
parent := newChangeSet()
parent.set([]byte("k3"), []byte("v3"))
parent.set([]byte("k2"), []byte("v2"))
cache := newChangeSet()
cache.set([]byte("k4"), []byte("v4"))
cache.set([]byte("k1"), []byte("v1"))
return mergeIterators(must(parent.reverseIterator(nil, nil)), must(cache.reverseIterator(nil, nil)), false)
},
expected: []string{"k4", "k3", "k2", "k1"},
},
}
for name, spec := range tests {
t.Run(name, func(t *testing.T) {
var got []string
for iter := spec.setup(); iter.Valid(); iter.Next() {
got = append(got, string(iter.Key()))
}
if !reflect.DeepEqual(spec.expected, got) {
t.Errorf("expected: %#v, got: %#v", spec.expected, got)
}
})
}
}

func TestBreakBtree(t *testing.T) {
myPrefix, otherPrefix := byte(0x01), byte(0x02)
parent := newChangeSet()
for i := byte(0); i < 63; i++ { // set to 63 elements to have a node split on the next insert
parent.set([]byte{myPrefix, i}, []byte{i})
}
it, _ := parent.reverseIterator([]byte{myPrefix, 32}, []byte{myPrefix, 34}) // ValidatorsPowerStoreIterator
if !it.Valid() {
t.Fatal("expected valid iterator")
}
// when btree is modified on a non conflicting key
parent.set([]byte{otherPrefix, byte(1)}, []byte("any value")) // SetLastValidatorPower

// then
var got [][2][]byte
for ; it.Valid(); it.Next() {
t.Logf("got key: %x\n", it.Key())
got = append(got, [2][]byte{it.Key(), it.Value()})
}
exp := [][2][]byte{
{{myPrefix, byte(33)}, []byte{33}},
{{myPrefix, byte(32)}, []byte{32}},
}
if !reflect.DeepEqual(exp, got) {
t.Errorf("expected %#v, got %#v", exp, got)
}
// and when new data is stored
parent.set([]byte{otherPrefix, byte(2)}, []byte("other value"))
// then
gotVal, ok := parent.get([]byte{otherPrefix, byte(2)})
if !ok {
t.Fatal("not found")
}
expVal := []byte("other value")
if bytes.Compare(gotVal, expVal) != 0 {
t.Errorf("expected %#v, got %#v", expVal, gotVal)
}

}
Loading

0 comments on commit 4f4db31

Please sign in to comment.